From f431d84c379f376b56c0adc9804ac52da992cbe0 Mon Sep 17 00:00:00 2001 From: Noah Negrey Date: Wed, 29 Aug 2018 09:26:03 -0700 Subject: [PATCH] =?UTF-8?q?Moving=20the=20Dialogflow=20samples=20to=20the?= =?UTF-8?q?=20python-docs-sampl=E2=80=A6=20[(#1629)](https://github.com/Go?= =?UTF-8?q?ogleCloudPlatform/python-docs-samples/issues/1629)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [DO_NOT_MERGE] Moving the Dialogflow samples to the python-docs-samples repo * Add missing region tags for tracking * Style updates --- dialogflow/README.rst | 632 ++++++++++++++++++ dialogflow/README.rst.in | 55 ++ dialogflow/context_management.py | 133 ++++ dialogflow/context_management_test.py | 44 ++ dialogflow/detect_intent_audio.py | 99 +++ dialogflow/detect_intent_audio_test.py | 35 + dialogflow/detect_intent_knowledge.py | 107 +++ dialogflow/detect_intent_stream.py | 120 ++++ dialogflow/detect_intent_stream_test.py | 32 + dialogflow/detect_intent_texts.py | 90 +++ dialogflow/detect_intent_texts_test.py | 30 + .../detect_intent_with_model_selection.py | 100 +++ ...detect_intent_with_model_selection_test.py | 37 + .../detect_intent_with_sentiment_analysis.py | 105 +++ ...ect_intent_with_sentiment_analysis_test.py | 32 + ...etect_intent_with_texttospeech_response.py | 98 +++ ..._intent_with_texttospeech_response_test.py | 35 + dialogflow/document_management.py | 216 ++++++ dialogflow/entity_management.py | 140 ++++ dialogflow/entity_management_test.py | 90 +++ dialogflow/entity_type_management.py | 131 ++++ dialogflow/intent_management.py | 169 +++++ dialogflow/intent_management_test.py | 68 ++ dialogflow/knowledge_base_management.py | 153 +++++ dialogflow/knowledge_base_management_test.py | 107 +++ dialogflow/requirements.txt | 1 + dialogflow/resources/230pm.wav | Bin 0 -> 55072 bytes dialogflow/resources/RoomReservation.zip | Bin 0 -> 10922 bytes dialogflow/resources/book_a_room.wav | Bin 0 -> 31058 bytes dialogflow/resources/half_an_hour.wav | Bin 0 -> 36154 bytes dialogflow/resources/mountain_view.wav | Bin 0 -> 33910 bytes dialogflow/resources/today.wav | Bin 0 -> 22998 bytes dialogflow/resources/two_people.wav | Bin 0 -> 31108 bytes dialogflow/session_entity_type_management.py | 160 +++++ .../session_entity_type_management_test.py | 63 ++ 35 files changed, 3082 insertions(+) create mode 100644 dialogflow/README.rst create mode 100644 dialogflow/README.rst.in create mode 100644 dialogflow/context_management.py create mode 100644 dialogflow/context_management_test.py create mode 100644 dialogflow/detect_intent_audio.py create mode 100644 dialogflow/detect_intent_audio_test.py create mode 100644 dialogflow/detect_intent_knowledge.py create mode 100644 dialogflow/detect_intent_stream.py create mode 100644 dialogflow/detect_intent_stream_test.py create mode 100644 dialogflow/detect_intent_texts.py create mode 100644 dialogflow/detect_intent_texts_test.py create mode 100644 dialogflow/detect_intent_with_model_selection.py create mode 100644 dialogflow/detect_intent_with_model_selection_test.py create mode 100644 dialogflow/detect_intent_with_sentiment_analysis.py create mode 100644 dialogflow/detect_intent_with_sentiment_analysis_test.py create mode 100644 dialogflow/detect_intent_with_texttospeech_response.py create mode 100644 dialogflow/detect_intent_with_texttospeech_response_test.py create mode 100644 dialogflow/document_management.py create mode 100644 dialogflow/entity_management.py create mode 100644 dialogflow/entity_management_test.py create mode 100644 dialogflow/entity_type_management.py create mode 100644 dialogflow/intent_management.py create mode 100644 dialogflow/intent_management_test.py create mode 100644 dialogflow/knowledge_base_management.py create mode 100644 dialogflow/knowledge_base_management_test.py create mode 100644 dialogflow/requirements.txt create mode 100644 dialogflow/resources/230pm.wav create mode 100644 dialogflow/resources/RoomReservation.zip create mode 100644 dialogflow/resources/book_a_room.wav create mode 100644 dialogflow/resources/half_an_hour.wav create mode 100644 dialogflow/resources/mountain_view.wav create mode 100644 dialogflow/resources/today.wav create mode 100644 dialogflow/resources/two_people.wav create mode 100644 dialogflow/session_entity_type_management.py create mode 100644 dialogflow/session_entity_type_management_test.py diff --git a/dialogflow/README.rst b/dialogflow/README.rst new file mode 100644 index 000000000000..bcbe73777cf9 --- /dev/null +++ b/dialogflow/README.rst @@ -0,0 +1,632 @@ +.. This file is automatically generated. Do not edit this file directly. + +Dialogflow Enterprise Edition API Python Samples +=============================================================================== + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/README.rst + + +This directory contains samples for Dialogflow Enterprise Edition API. The `Dialogflow Enterprise Edition API`_ enables you to create conversational experiences across devices and platforms. + + + + +.. _Dialogflow Enterprise Edition API: https://cloud.google.com/dialogflow-enterprise/docs/ + +Setup +------------------------------------------------------------------------------- + + +Authentication +++++++++++++++ + +This sample requires you to have authentication setup. Refer to the +`Authentication Getting Started Guide`_ for instructions on setting up +credentials for applications. + +.. _Authentication Getting Started Guide: + https://cloud.google.com/docs/authentication/getting-started + +Install Dependencies +++++++++++++++++++++ + +#. Clone the repository and change directory to the sample directory. + + .. code-block:: bash + + $ git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git + +#. Install `pip`_ and `virtualenv`_ if you do not already have them. You may want to refer to the `Python Development Environment Setup Guide`_ for Google Cloud Platform for instructions. + + .. _Python Development Environment Setup Guide: + https://cloud.google.com/python/setup + +#. Create a virtualenv. Samples are compatible with Python 2.7 and 3.4+. + + .. code-block:: bash + + $ virtualenv env + $ source env/bin/activate + +#. Install the dependencies needed to run the samples. + + .. code-block:: bash + + $ pip install -r requirements.txt + +.. _pip: https://pip.pypa.io/ +.. _virtualenv: https://virtualenv.pypa.io/ + +Samples +------------------------------------------------------------------------------- + +Detect Intent Text ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_texts.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_texts.py + + usage: detect_intent_texts.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + texts [texts ...] + + DialogFlow API Detect Intent Python sample with text inputs. + + Examples: + python detect_intent_texts.py -h + python detect_intent_texts.py --project-id PROJECT_ID --session-id SESSION_ID "hello" "book a meeting room" "Mountain View" + python detect_intent_texts.py --project-id PROJECT_ID --session-id SESSION_ID "tomorrow" "10 AM" "2 hours" "10 people" "A" "yes" + + positional arguments: + texts Text inputs. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + + + +Detect Intent Audio ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_audio.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_audio.py + + usage: detect_intent_audio.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --audio-file-path AUDIO_FILE_PATH + + DialogFlow API Detect Intent Python sample with audio file. + + Examples: + python detect_intent_audio.py -h + python detect_intent_audio.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/book_a_room.wav + python detect_intent_audio.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/mountain_view.wav + python detect_intent_audio.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/today.wav + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --audio-file-path AUDIO_FILE_PATH + Path to the audio file. + + + +Detect Intent Stream ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_stream.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_stream.py + + usage: detect_intent_stream.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --audio-file-path AUDIO_FILE_PATH + + DialogFlow API Detect Intent Python sample with audio files processed + as an audio stream. + + Examples: + python detect_intent_stream.py -h + python detect_intent_stream.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/book_a_room.wav + python detect_intent_stream.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/mountain_view.wav + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --audio-file-path AUDIO_FILE_PATH + Path to the audio file. + + + +Detect Intent Knowledge Base ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_knowledge.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_knowledge.py + + usage: detect_intent_knowledge.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --knowledge-base-id KNOWLEDGE_ID + texts [texts ...] + + Dialogflow API Detect Intent Python sample with text inputs. + + Examples: + python detect_intent_knowledge.py -h + python detect_intent_knowledge.py --project-id PROJECT_ID --session-id SESSION_ID --knowledge-base-id KNOWLEDGE_ID "hello" "how do I reset my password?" + + positional arguments: + texts Text inputs. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + ID of the DetectIntent session. Defaults to a random + UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --knowledge-base-id KNOWLEDGE_ID + The id of the Knowledge Base to query against, e.g., OTE5NjYzMTkxNDA2NzI2MzQ4OA + + + +Detect Intent with Model Selection ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_with_model_selection.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_with_model_selection.py + + usage: detect_intent_with_model_selection.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + --audio-file-path AUDIO_FILE_PATH + + Dialogflow API Beta Detect Intent Python sample with model selection. + + Examples: + python detect_intent_with_model_selection.py -h + python detect_intent_with_model_selection.py --project-id PROJECT_ID --session-id SESSION_ID --audio-file-path resources/book_a_room.wav + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + --audio-file-path AUDIO_FILE_PATH + Path to the audio file. + + + +Detect Intent with Sentiment Analysis ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_with_sentiment_analysis.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_with_sentiment_analysis.py + + usage: detect_intent_with_sentiment_analysis.py [-h] --project-id PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + texts [texts ...] + + Dialogflow API Beta Detect Intent Python sample with sentiment analysis. + + Examples: + python detect_intent_with_sentiment_analysis.py -h + python detect_intent_with_sentiment_analysis.py --project-id PROJECT_ID --session-id SESSION_ID "hello" "book a meeting room" "Mountain View" + + positional arguments: + texts Text inputs. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + + + +Detect Intent with Text to Speech Response ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/detect_intent_with_texttospeech_response.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python detect_intent_with_texttospeech_response.py + + usage: detect_intent_with_texttospeech_response.py [-h] --project-id + PROJECT_ID + [--session-id SESSION_ID] + [--language-code LANGUAGE_CODE] + texts [texts ...] + + Dialogflow API Beta Detect Intent Python sample with an audio response. + + Examples: + python detect_intent_with_texttospeech_response.py -h + python detect_intent_with_texttospeech_response.py --project-id PROJECT_ID --session-id SESSION_ID "hello" + + positional arguments: + texts Text inputs. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + --session-id SESSION_ID + Identifier of the DetectIntent session. Defaults to a + random UUID. + --language-code LANGUAGE_CODE + Language code of the query. Defaults to "en-US". + + + +Intent Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/intent_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python intent_management.py + + usage: intent_management.py [-h] --project-id PROJECT_ID + {list,create,delete} ... + + DialogFlow API Intent Python sample showing how to manage intents. + + Examples: + python intent_management.py -h + python intent_management.py --project-id PROJECT_ID list + python intent_management.py --project-id PROJECT_ID create "room.cancellation - yes" --training-phrases-parts "cancel" "cancellation" --message-texts "Are you sure you want to cancel?" "Cancelled." + python intent_management.py --project-id PROJECT_ID delete 74892d81-7901-496a-bb0a-c769eda5180e + + positional arguments: + {list,create,delete} + list + create Create an intent of the given intent type. + delete Delete intent with the given intent type and intent + value. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + + + +Entity Type Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/entity_type_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python entity_type_management.py + + usage: entity_type_management.py [-h] --project-id PROJECT_ID + {list,create,delete} ... + + DialogFlow API EntityType Python sample showing how to manage entity types. + + Examples: + python entity_type_management.py -h + python entity_type_management.py --project-id PROJECT_ID list + python entity_type_management.py --project-id PROJECT_ID create employee + python entity_type_management.py --project-id PROJECT_ID delete e57238e2-e692-44ea-9216-6be1b2332e2a + + positional arguments: + {list,create,delete} + list + create Create an entity type with the given display name. + delete Delete entity type with the given entity type name. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + + + +Entity Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/entity_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python entity_management.py + + usage: entity_management.py [-h] --project-id PROJECT_ID + {list,create,delete} ... + + DialogFlow API Entity Python sample showing how to manage entities. + + Examples: + python entity_management.py -h + python entity_management.py --project-id PROJECT_ID list --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a + python entity_management.py --project-id PROJECT_ID create new_room --synonyms basement cellar --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a + python entity_management.py --project-id PROJECT_ID delete new_room --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a + + positional arguments: + {list,create,delete} + list + create Create an entity of the given entity type. + delete Delete entity with the given entity type and entity + value. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + + + +Session Entity Type Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/session_entity_type_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python session_entity_type_management.py + + usage: session_entity_type_management.py [-h] --project-id PROJECT_ID + {list,create,delete} ... + + DialogFlow API SessionEntityType Python sample showing how to manage + session entity types. + + Examples: + python session_entity_type_management.py -h + python session_entity_type_management.py --project-id PROJECT_ID list --session-id SESSION_ID + python session_entity_type_management.py --project-id PROJECT_ID create --session-id SESSION_ID --entity-type-display-name room --entity-values C D E F + python session_entity_type_management.py --project-id PROJECT_ID delete --session-id SESSION_ID --entity-type-display-name room + + positional arguments: + {list,create,delete} + list + create Create a session entity type with the given display + name. + delete Delete session entity type with the given entity type + display name. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. Required. + + + +Knowledge Base Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/knowledge_base_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python knowledge_base_management.py + + usage: knowledge_base_management.py [-h] --project-id PROJECT_ID + {list,create,get,delete} ... + + Dialogflow API Python sample showing how to manage Knowledge bases. + + Examples: + python knowledge_base_management.py -h + python knowledge_base_management.py --project-id PROJECT_ID list + python knowledge_base_management.py --project-id PROJECT_ID create --display-name DISPLAY_NAME + python knowledge_base_management.py --project-id PROJECT_ID get --knowledge-base-id knowledge_base_id + python knowledge_base_management.py --project-id PROJECT_ID delete --knowledge-base-id knowledge_base_id + + positional arguments: + {list,create,get,delete} + list List all Knowledge bases that belong to the project. + create Create a new Knowledge base. + get Get a Knowledge base by its id. + delete Delete a Knowledge base by its id. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project/agent id. + + + +Document Management ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +.. image:: https://gstatic.com/cloudssh/images/open-btn.png + :target: https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/GoogleCloudPlatform/python-docs-samples&page=editor&open_in_editor=/document_management.py,/README.rst + + + + +To run this sample: + +.. code-block:: bash + + $ python document_management.py + + usage: document_management.py [-h] --project-id PROJECT_ID --knowledge-base-id + KNOWLEDGE_BASE_ID + {list,create,get,delete} ... + + Dialogflow API Python sample showing how to manage Knowledge Documents. + + Examples: + python document_management.py -h + python document_management.py --project-id PROJECT_ID --knowledge-base-id knowledge_base_id list + python document_management.py --project-id PROJECT_ID --knowledge-base-id knowledge_base_id create --display-name DISPLAY_NAME --mime-type MIME_TYPE --knowledge-type KNOWLEDGE_TYPE --content-uri CONTENT_URI + python document_management.py --project-id PROJECT_ID --knowledge-base-id knowledge_base_id get --document-id DOCUMENT_ID + python document_management.py --project-id PROJECT_ID --knowledge-base-id knowledge_base_id delete --document-id DOCUMENT_ID + + positional arguments: + {list,create,get,delete} + list List all Documents that belong to a certain Knowledge + base. + create Create a Document for a certain Knowledge base. Please note that it will be initially disabled until you enable it. + get Get a Document by its id and the Knowledge base id. + delete Delete a Document by its id and the Knowledge baseid. + + optional arguments: + -h, --help show this help message and exit + --project-id PROJECT_ID + Project id. Required. + --knowledge-base-id KNOWLEDGE_BASE_ID + The id of the Knowledge Base that the Document belongs + to, e.g., OTE5NjYzMTkxNDA2NzI2MzQ4OA + --mime_type The mime_type of the Document. e.g. text/csv, text/html, + text/plain, text/pdf etc. + + --knowledge_type The Knowledge type of the Document. e.g. FAQ, EXTRACTIVE_QA. + + --content_uri Uri of the document, e.g. gs://path/mydoc.csv, + http://mypage.com/faq.html. + + + + + + + + +The client library +------------------------------------------------------------------------------- + +This sample uses the `Google Cloud Client Library for Python`_. +You can read the documentation for more details on API usage and use GitHub +to `browse the source`_ and `report issues`_. + +.. _Google Cloud Client Library for Python: + https://googlecloudplatform.github.io/google-cloud-python/ +.. _browse the source: + https://github.com/GoogleCloudPlatform/google-cloud-python +.. _report issues: + https://github.com/GoogleCloudPlatform/google-cloud-python/issues + + +.. _Google Cloud SDK: https://cloud.google.com/sdk/ diff --git a/dialogflow/README.rst.in b/dialogflow/README.rst.in new file mode 100644 index 000000000000..250055c43d69 --- /dev/null +++ b/dialogflow/README.rst.in @@ -0,0 +1,55 @@ +# This file is used to generate README.rst + +product: + name: Dialogflow Enterprise Edition API + short_name: Dialogflow API + url: https://cloud.google.com/dialogflow-enterprise/docs/ + description: > + The `Dialogflow Enterprise Edition API`_ enables you to create conversational experiences across devices and platforms. + +setup: +- auth +- install_deps + +samples: +- name: Detect Intent Text + file: detect_intent_texts.py + show_help: True +- name: Detect Intent Audio + file: detect_intent_audio.py + show_help: True +- name: Detect Intent Stream + file: detect_intent_stream.py + show_help: True +- name: Detect Intent Knowledge Base + file: detect_intent_knowledge.py + show_help: True +- name: Detect Intent with Model Selection + file: detect_intent_with_model_selection.py + show_help: True +- name: Detect Intent with Sentiment Analysis + file: detect_intent_with_sentiment_analysis.py + show_help: True +- name: Detect Intent with Text to Speech Response + file: detect_intent_with_texttospeech_response.py + show_help: True +- name: Intent Management + file: intent_management.py + show_help: True +- name: Entity Type Management + file: entity_type_management.py + show_help: True +- name: Entity Management + file: entity_management.py + show_help: True +- name: Session Entity Type Management + file: session_entity_type_management.py + show_help: True +- name: Knowledge Base Management + file: knowledge_base_management.py + show_help: True +- name: Document Management + file: document_management.py + show_help: True + +cloud_client_library: true diff --git a/dialogflow/context_management.py b/dialogflow/context_management.py new file mode 100644 index 000000000000..d2a75bd711ad --- /dev/null +++ b/dialogflow/context_management.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Context Python sample showing how to manage session +contexts. + +Examples: + python context_management.py -h + python context_management.py --project-id PROJECT_ID \ + list --session-id SESSION_ID + python context_management.py --project-id PROJECT_ID \ + create --session-id SESSION_ID --context-id CONTEXT_ID + python context_management.py --project-id PROJECT_ID \ + delete --session-id SESSION_ID --context-id CONTEXT_ID +""" + +import argparse + + +# [START dialogflow_list_contexts] +def list_contexts(project_id, session_id): + import dialogflow_v2 as dialogflow + contexts_client = dialogflow.ContextsClient() + + session_path = contexts_client.session_path(project_id, session_id) + + contexts = contexts_client.list_contexts(session_path) + + print('Contexts for session {}:\n'.format(session_path)) + for context in contexts: + print('Context name: {}'.format(context.name)) + print('Lifespan count: {}'.format(context.lifespan_count)) + print('Fields:') + for field, value in context.parameters.fields.items(): + if value.string_value: + print('\t{}: {}'.format(field, value)) +# [END dialogflow_list_contexts] + + +# [START dialogflow_create_context] +def create_context(project_id, session_id, context_id, lifespan_count): + import dialogflow_v2 as dialogflow + contexts_client = dialogflow.ContextsClient() + + session_path = contexts_client.session_path(project_id, session_id) + context_name = contexts_client.context_path( + project_id, session_id, context_id) + + context = dialogflow.types.Context( + name=context_name, lifespan_count=lifespan_count) + + response = contexts_client.create_context(session_path, context) + + print('Context created: \n{}'.format(response)) +# [END dialogflow_create_context] + + +# [START dialogflow_delete_context] +def delete_context(project_id, session_id, context_id): + import dialogflow_v2 as dialogflow + contexts_client = dialogflow.ContextsClient() + + context_name = contexts_client.context_path( + project_id, session_id, context_id) + + contexts_client.delete_context(context_name) +# [END dialogflow_delete_context] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help=list_contexts.__doc__) + list_parser.add_argument( + '--session-id', + required=True) + + create_parser = subparsers.add_parser( + 'create', help=create_context.__doc__) + create_parser.add_argument( + '--session-id', + required=True) + create_parser.add_argument( + '--context-id', + help='The id of the context.', + required=True) + create_parser.add_argument( + '--lifespan-count', + help='The lifespan_count of the context. Defaults to 1.', + default=1) + + delete_parser = subparsers.add_parser( + 'delete', help=delete_context.__doc__) + delete_parser.add_argument( + '--session-id', + required=True) + delete_parser.add_argument( + '--context-id', + help='The id of the context.', + required=True) + + args = parser.parse_args() + + if args.command == 'list': + list_contexts(args.project_id, args.session_id, ) + elif args.command == 'create': + create_context( + args.project_id, args.session_id, args.context_id, + args.lifespan_count) + elif args.command == 'delete': + delete_context(args.project_id, args.session_id, args.context_id) diff --git a/dialogflow/context_management_test.py b/dialogflow/context_management_test.py new file mode 100644 index 000000000000..8460a9c65fb3 --- /dev/null +++ b/dialogflow/context_management_test.py @@ -0,0 +1,44 @@ +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +import context_management +import detect_intent_texts + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +CONTEXT_ID = 'fake_context_for_testing' + + +def test_create_context(capsys): + # Calling detect intent to create a session. + detect_intent_texts.detect_intent_texts( + PROJECT_ID, SESSION_ID, ['hi'], 'en-US') + + context_management.create_context(PROJECT_ID, SESSION_ID, CONTEXT_ID, 1) + context_management.list_contexts(PROJECT_ID, SESSION_ID) + + out, _ = capsys.readouterr() + assert CONTEXT_ID in out + + +def test_delete_context(capsys): + context_management.delete_context(PROJECT_ID, SESSION_ID, CONTEXT_ID) + context_management.list_contexts(PROJECT_ID, SESSION_ID) + + out, _ = capsys.readouterr() + assert CONTEXT_ID not in out diff --git a/dialogflow/detect_intent_audio.py b/dialogflow/detect_intent_audio.py new file mode 100644 index 000000000000..7dcef341a8a6 --- /dev/null +++ b/dialogflow/detect_intent_audio.py @@ -0,0 +1,99 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Detect Intent Python sample with audio file. + +Examples: + python detect_intent_audio.py -h + python detect_intent_audio.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/book_a_room.wav + python detect_intent_audio.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/mountain_view.wav + python detect_intent_audio.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/today.wav +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_audio] +def detect_intent_audio(project_id, session_id, audio_file_path, + language_code): + """Returns the result of detect intent with an audio file as input. + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2 as dialogflow + + session_client = dialogflow.SessionsClient() + + # Note: hard coding audio_encoding and sample_rate_hertz for simplicity. + audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16 + sample_rate_hertz = 16000 + + session = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session)) + + with open(audio_file_path, 'rb') as audio_file: + input_audio = audio_file.read() + + audio_config = dialogflow.types.InputAudioConfig( + audio_encoding=audio_encoding, language_code=language_code, + sample_rate_hertz=sample_rate_hertz) + query_input = dialogflow.types.QueryInput(audio_config=audio_config) + + response = session_client.detect_intent( + session=session, query_input=query_input, + input_audio=input_audio) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) +# [END dialogflow_detect_intent_audio] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + '--audio-file-path', + help='Path to the audio file.', + required=True) + + args = parser.parse_args() + + detect_intent_audio( + args.project_id, args.session_id, args.audio_file_path, + args.language_code) diff --git a/dialogflow/detect_intent_audio_test.py b/dialogflow/detect_intent_audio_test.py new file mode 100644 index 000000000000..5f67f6ef1495 --- /dev/null +++ b/dialogflow/detect_intent_audio_test.py @@ -0,0 +1,35 @@ +# Copyright 2017, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_audio import detect_intent_audio + +DIRNAME = os.path.realpath(os.path.dirname(__file__)) +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +AUDIOS = [ + '{0}/resources/book_a_room.wav'.format(DIRNAME), + '{0}/resources/mountain_view.wav'.format(DIRNAME), + '{0}/resources/today.wav'.format(DIRNAME), +] + + +def test_detect_intent_audio(capsys): + for audio_file_path in AUDIOS: + detect_intent_audio(PROJECT_ID, SESSION_ID, audio_file_path, 'en-US') + out, _ = capsys.readouterr() + + assert 'Fulfillment text: What time will the meeting start?' in out diff --git a/dialogflow/detect_intent_knowledge.py b/dialogflow/detect_intent_knowledge.py new file mode 100644 index 000000000000..edfd4b517ec8 --- /dev/null +++ b/dialogflow/detect_intent_knowledge.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Detect Knowledge Base Intent Python sample with text inputs. + +Examples: + python detect_intent_knowledge.py -h + python detect_intent_knowledge.py --project-id PROJECT_ID \ + --session-id SESSION_ID --knowledge-base-id KNOWLEDGE_BASE_ID \ + "hello" "how do I reset my password?" +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_knowledge] +def detect_intent_knowledge(project_id, session_id, language_code, + knowledge_base_id, texts): + """Returns the result of detect intent with querying Knowledge Connector. + + Args: + project_id: The GCP project linked with the agent you are going to query. + session_id: Id of the session, using the same `session_id` between requests + allows continuation of the conversation. + language_code: Language of the queries. + knowledge_base_id: The Knowledge base's id to query against. + texts: A list of text queries to send. + """ + import dialogflow_v2beta1 as dialogflow + session_client = dialogflow.SessionsClient() + + session_path = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session_path)) + + for text in texts: + text_input = dialogflow.types.TextInput( + text=text, language_code=language_code) + + query_input = dialogflow.types.QueryInput(text=text_input) + + knowledge_base_path = dialogflow.knowledge_bases_client \ + .KnowledgeBasesClient \ + .knowledge_base_path(project_id, knowledge_base_id) + + query_params = dialogflow.types.QueryParameters( + knowledge_base_names=[knowledge_base_path]) + + response = session_client.detect_intent( + session=session_path, query_input=query_input, + query_params=query_params) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) + print('Knowledge results:') + knowledge_answers = response.query_result.knowledge_answers + for answers in knowledge_answers.answers: + print(' - Answer: {}'.format(answers.answer)) + print(' - Confidence: {}'.format( + answers.match_confidence)) +# [END dialogflow_detect_intent_knowledge] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', help='Project/agent id. Required.', required=True) + parser.add_argument( + '--session-id', + help='ID of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + '--knowledge-base-id', + help='The id of the Knowledge Base to query against', + required=True) + parser.add_argument('texts', nargs='+', type=str, help='Text inputs.') + + args = parser.parse_args() + + detect_intent_knowledge(args.project_id, args.session_id, + args.language_code, args.knowledge_base_id, + args.texts) diff --git a/dialogflow/detect_intent_stream.py b/dialogflow/detect_intent_stream.py new file mode 100644 index 000000000000..e69d46c25bbb --- /dev/null +++ b/dialogflow/detect_intent_stream.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Detect Intent Python sample with audio files processed +as an audio stream. + +Examples: + python detect_intent_stream.py -h + python detect_intent_stream.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/book_a_room.wav + python detect_intent_stream.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/mountain_view.wav +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_streaming] +def detect_intent_stream(project_id, session_id, audio_file_path, + language_code): + """Returns the result of detect intent with streaming audio as input. + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2 as dialogflow + session_client = dialogflow.SessionsClient() + + # Note: hard coding audio_encoding and sample_rate_hertz for simplicity. + audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16 + sample_rate_hertz = 16000 + + session_path = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session_path)) + + def request_generator(audio_config, audio_file_path): + query_input = dialogflow.types.QueryInput(audio_config=audio_config) + + # The first request contains the configuration. + yield dialogflow.types.StreamingDetectIntentRequest( + session=session_path, query_input=query_input) + + # Here we are reading small chunks of audio data from a local + # audio file. In practice these chunks should come from + # an audio input device. + with open(audio_file_path, 'rb') as audio_file: + while True: + chunk = audio_file.read(4096) + if not chunk: + break + # The later requests contains audio data. + yield dialogflow.types.StreamingDetectIntentRequest( + input_audio=chunk) + + audio_config = dialogflow.types.InputAudioConfig( + audio_encoding=audio_encoding, language_code=language_code, + sample_rate_hertz=sample_rate_hertz) + + requests = request_generator(audio_config, audio_file_path) + responses = session_client.streaming_detect_intent(requests) + + print('=' * 20) + for response in responses: + print('Intermediate transcript: "{}".'.format( + response.recognition_result.transcript)) + + # Note: The result from the last response is the final transcript along + # with the detected content. + query_result = response.query_result + + print('=' * 20) + print('Query text: {}'.format(query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + query_result.intent.display_name, + query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + query_result.fulfillment_text)) +# [END dialogflow_detect_intent_streaming] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + '--audio-file-path', + help='Path to the audio file.', + required=True) + + args = parser.parse_args() + + detect_intent_stream( + args.project_id, args.session_id, args.audio_file_path, + args.language_code) diff --git a/dialogflow/detect_intent_stream_test.py b/dialogflow/detect_intent_stream_test.py new file mode 100644 index 000000000000..f83ab07b5e67 --- /dev/null +++ b/dialogflow/detect_intent_stream_test.py @@ -0,0 +1,32 @@ +# Copyright 2017, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_stream import detect_intent_stream + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +AUDIO_FILE_PATH = '{0}/resources/book_a_room.wav'.format( + os.path.realpath(os.path.dirname(__file__)), +) + + +def test_detect_intent_stream(capsys): + detect_intent_stream(PROJECT_ID, SESSION_ID, AUDIO_FILE_PATH, 'en-US') + out, _ = capsys.readouterr() + + assert 'Intermediate transcript: "book"' in out + assert 'Fulfillment text: What time will the meeting start?' in out diff --git a/dialogflow/detect_intent_texts.py b/dialogflow/detect_intent_texts.py new file mode 100644 index 000000000000..c1b8f04dfc59 --- /dev/null +++ b/dialogflow/detect_intent_texts.py @@ -0,0 +1,90 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Detect Intent Python sample with text inputs. + +Examples: + python detect_intent_texts.py -h + python detect_intent_texts.py --project-id PROJECT_ID \ + --session-id SESSION_ID \ + "hello" "book a meeting room" "Mountain View" + python detect_intent_texts.py --project-id PROJECT_ID \ + --session-id SESSION_ID \ + "tomorrow" "10 AM" "2 hours" "10 people" "A" "yes" +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_text] +def detect_intent_texts(project_id, session_id, texts, language_code): + """Returns the result of detect intent with texts as inputs. + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2 as dialogflow + session_client = dialogflow.SessionsClient() + + session = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session)) + + for text in texts: + text_input = dialogflow.types.TextInput( + text=text, language_code=language_code) + + query_input = dialogflow.types.QueryInput(text=text_input) + + response = session_client.detect_intent( + session=session, query_input=query_input) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) +# [END dialogflow_detect_intent_text] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + 'texts', + nargs='+', + type=str, + help='Text inputs.') + + args = parser.parse_args() + + detect_intent_texts( + args.project_id, args.session_id, args.texts, args.language_code) diff --git a/dialogflow/detect_intent_texts_test.py b/dialogflow/detect_intent_texts_test.py new file mode 100644 index 000000000000..1995b9b3d26b --- /dev/null +++ b/dialogflow/detect_intent_texts_test.py @@ -0,0 +1,30 @@ +# Copyright 2017, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_texts import detect_intent_texts + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +TEXTS = ["hello", "book a meeting room", "Mountain View", + "tomorrow", "10 AM", "2 hours", "10 people", "A", "yes"] + + +def test_detect_intent_texts(capsys): + detect_intent_texts(PROJECT_ID, SESSION_ID, TEXTS, 'en-US') + out, _ = capsys.readouterr() + + assert 'Fulfillment text: All set!' in out diff --git a/dialogflow/detect_intent_with_model_selection.py b/dialogflow/detect_intent_with_model_selection.py new file mode 100644 index 000000000000..723170ee9fe1 --- /dev/null +++ b/dialogflow/detect_intent_with_model_selection.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Beta Detect Intent Python sample with model selection. + +Examples: + python detect_intent_with_model_selection.py -h + python detect_intent_with_model_selection.py --project-id PROJECT_ID \ + --session-id SESSION_ID --audio-file-path resources/book_a_room.wav +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_with_model_selection] +def detect_intent_with_model_selection(project_id, session_id, audio_file_path, + language_code): + """Returns the result of detect intent with model selection on an audio file + as input + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2beta1 as dialogflow + session_client = dialogflow.SessionsClient() + + # Note: hard coding audio_encoding and sample_rate_hertz for simplicity. + audio_encoding = dialogflow.enums.AudioEncoding.AUDIO_ENCODING_LINEAR_16 + sample_rate_hertz = 16000 + + session_path = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session_path)) + + with open(audio_file_path, 'rb') as audio_file: + input_audio = audio_file.read() + + # Which Speech model to select for the given request. + # Possible models: video, phone_call, command_and_search, default + model = 'phone_call' + + audio_config = dialogflow.types.InputAudioConfig( + audio_encoding=audio_encoding, language_code=language_code, + sample_rate_hertz=sample_rate_hertz, + model=model) + query_input = dialogflow.types.QueryInput(audio_config=audio_config) + + response = session_client.detect_intent( + session=session_path, query_input=query_input, + input_audio=input_audio) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) +# [END dialogflow_detect_intent_with_model_selection] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + '--audio-file-path', + help='Path to the audio file.', + required=True) + + args = parser.parse_args() + + detect_intent_with_model_selection( + args.project_id, args.session_id, args.audio_file_path, + args.language_code) diff --git a/dialogflow/detect_intent_with_model_selection_test.py b/dialogflow/detect_intent_with_model_selection_test.py new file mode 100644 index 000000000000..127622893312 --- /dev/null +++ b/dialogflow/detect_intent_with_model_selection_test.py @@ -0,0 +1,37 @@ +# Copyright 2018, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_with_model_selection import \ + detect_intent_with_model_selection + +DIRNAME = os.path.realpath(os.path.dirname(__file__)) +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +AUDIOS = [ + '{0}/resources/book_a_room.wav'.format(DIRNAME), + '{0}/resources/mountain_view.wav'.format(DIRNAME), + '{0}/resources/today.wav'.format(DIRNAME), +] + + +def test_detect_intent_audio_with_model_selection(capsys): + for audio_file_path in AUDIOS: + detect_intent_with_model_selection(PROJECT_ID, SESSION_ID, + audio_file_path, 'en-US') + out, _ = capsys.readouterr() + + assert 'Fulfillment text: What time will the meeting start?' in out diff --git a/dialogflow/detect_intent_with_sentiment_analysis.py b/dialogflow/detect_intent_with_sentiment_analysis.py new file mode 100644 index 000000000000..4eb4babf29f1 --- /dev/null +++ b/dialogflow/detect_intent_with_sentiment_analysis.py @@ -0,0 +1,105 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Beta Detect Intent Python sample with sentiment analysis. + +Examples: + python detect_intent_with_sentiment_analysis.py -h + python detect_intent_with_sentiment_analysis.py --project-id PROJECT_ID \ + --session-id SESSION_ID \ + "hello" "book a meeting room" "Mountain View" +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_with_sentiment_analysis] +def detect_intent_with_sentiment_analysis(project_id, session_id, texts, + language_code): + """Returns the result of detect intent with texts as inputs and analyzes the + sentiment of the query text. + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2beta1 as dialogflow + session_client = dialogflow.SessionsClient() + + session_path = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session_path)) + + for text in texts: + text_input = dialogflow.types.TextInput( + text=text, language_code=language_code) + + query_input = dialogflow.types.QueryInput(text=text_input) + + # Enable sentiment analysis + sentiment_config = dialogflow.types.SentimentAnalysisRequestConfig( + analyze_query_text_sentiment=True) + + # Set the query parameters with sentiment analysis + query_params = dialogflow.types.QueryParameters( + sentiment_analysis_request_config=sentiment_config) + + response = session_client.detect_intent( + session=session_path, query_input=query_input, + query_params=query_params) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) + # Score between -1.0 (negative sentiment) and 1.0 (positive sentiment). + print('Query Text Sentiment Score: {}\n'.format( + response.query_result.sentiment_analysis_result + .query_text_sentiment.score)) + print('Query Text Sentiment Magnitude: {}\n'.format( + response.query_result.sentiment_analysis_result + .query_text_sentiment.magnitude)) +# [END dialogflow_detect_intent_with_sentiment_analysis] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + 'texts', + nargs='+', + type=str, + help='Text inputs.') + + args = parser.parse_args() + + detect_intent_with_sentiment_analysis( + args.project_id, args.session_id, args.texts, args.language_code) diff --git a/dialogflow/detect_intent_with_sentiment_analysis_test.py b/dialogflow/detect_intent_with_sentiment_analysis_test.py new file mode 100644 index 000000000000..5e9041b177a1 --- /dev/null +++ b/dialogflow/detect_intent_with_sentiment_analysis_test.py @@ -0,0 +1,32 @@ +# Copyright 2018, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_with_sentiment_analysis import \ + detect_intent_with_sentiment_analysis + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +TEXTS = ["hello", "book a meeting room", "Mountain View", + "tomorrow", "10 AM", "2 hours", "10 people", "A", "yes"] + + +def test_detect_intent_with_sentiment_analysis(capsys): + detect_intent_with_sentiment_analysis(PROJECT_ID, SESSION_ID, TEXTS, + 'en-US') + out, _ = capsys.readouterr() + + assert 'Query Text Sentiment Score' in out diff --git a/dialogflow/detect_intent_with_texttospeech_response.py b/dialogflow/detect_intent_with_texttospeech_response.py new file mode 100644 index 000000000000..fbbf701da9d7 --- /dev/null +++ b/dialogflow/detect_intent_with_texttospeech_response.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Beta Detect Intent Python sample with an audio response. + +Examples: + python detect_intent_with_texttospeech_response_test.py -h + python detect_intent_with_texttospeech_response_test.py \ + --project-id PROJECT_ID --session-id SESSION_ID "hello" +""" + +import argparse +import uuid + + +# [START dialogflow_detect_intent_with_texttospeech_response] +def detect_intent_with_texttospeech_response(project_id, session_id, texts, + language_code): + """Returns the result of detect intent with texts as inputs and includes + the response in an audio format. + + Using the same `session_id` between requests allows continuation + of the conversaion.""" + import dialogflow_v2beta1 as dialogflow + session_client = dialogflow.SessionsClient() + + session_path = session_client.session_path(project_id, session_id) + print('Session path: {}\n'.format(session_path)) + + for text in texts: + text_input = dialogflow.types.TextInput( + text=text, language_code=language_code) + + query_input = dialogflow.types.QueryInput(text=text_input) + + # Set the query parameters with sentiment analysis + output_audio_config = dialogflow.types.OutputAudioConfig( + audio_encoding=dialogflow.enums.OutputAudioEncoding + .OUTPUT_AUDIO_ENCODING_LINEAR_16) + + response = session_client.detect_intent( + session=session_path, query_input=query_input, + output_audio_config=output_audio_config) + + print('=' * 20) + print('Query text: {}'.format(response.query_result.query_text)) + print('Detected intent: {} (confidence: {})\n'.format( + response.query_result.intent.display_name, + response.query_result.intent_detection_confidence)) + print('Fulfillment text: {}\n'.format( + response.query_result.fulfillment_text)) + # The response's audio_content is binary. + with open('output.wav', 'wb') as out: + out.write(response.output_audio) + print('Audio content written to file "output.wav"') +# [END dialogflow_detect_intent_with_texttospeech_response] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + parser.add_argument( + '--session-id', + help='Identifier of the DetectIntent session. ' + 'Defaults to a random UUID.', + default=str(uuid.uuid4())) + parser.add_argument( + '--language-code', + help='Language code of the query. Defaults to "en-US".', + default='en-US') + parser.add_argument( + 'texts', + nargs='+', + type=str, + help='Text inputs.') + + args = parser.parse_args() + + detect_intent_with_texttospeech_response( + args.project_id, args.session_id, args.texts, args.language_code) diff --git a/dialogflow/detect_intent_with_texttospeech_response_test.py b/dialogflow/detect_intent_with_texttospeech_response_test.py new file mode 100644 index 000000000000..96419b2f229d --- /dev/null +++ b/dialogflow/detect_intent_with_texttospeech_response_test.py @@ -0,0 +1,35 @@ +# Copyright 2018, Google LLC +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +from detect_intent_with_texttospeech_response import \ + detect_intent_with_texttospeech_response + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +TEXTS = ["hello"] + + +def test_detect_intent_with_sentiment_analysis(capsys): + detect_intent_with_texttospeech_response(PROJECT_ID, SESSION_ID, TEXTS, + 'en-US') + out, _ = capsys.readouterr() + + assert 'Audio content written to file' in out + statinfo = os.stat('output.wav') + assert statinfo.st_size > 0 + os.remove('output.wav') + assert not os.path.isfile('output.wav') diff --git a/dialogflow/document_management.py b/dialogflow/document_management.py new file mode 100644 index 000000000000..6145c9df8a6a --- /dev/null +++ b/dialogflow/document_management.py @@ -0,0 +1,216 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Python sample showing how to manage Knowledge Documents. + +Examples: + python document_management.py -h + python document_management.py --project-id PROJECT_ID \ + --knowledge-base-id knowledge_base_id \ + list + python document_management.py --project-id PROJECT_ID \ + --knowledge-base-id knowledge_base_id \ + create --display-name DISPLAY_NAME --mime-type MIME_TYPE \ + --knowledge-type KNOWLEDGE_TYPE --content-uri CONTENT_URI + python document_management.py --project-id PROJECT_ID \ + --knowledge-base-id knowledge_base_id \ + get --document-id DOCUMENT_ID + python document_management.py --project-id PROJECT_ID \ + --knowledge-base-id knowledge_base_id \ + delete --document-id DOCUMENT_ID +""" + +import argparse + + +KNOWLEDGE_TYPES = ['KNOWLEDGE_TYPE_UNSPECIFIED', 'FAQ', 'EXTRACTIVE_QA'] + + +# [START dialogflow_list_document] +def list_documents(project_id, knowledge_base_id): + """Lists the Documents belonging to a Knowledge base. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.DocumentsClient() + knowledge_base_path = client.knowledge_base_path(project_id, + knowledge_base_id) + + print('Documents for Knowledge Id: {}'.format(knowledge_base_id)) + for document in client.list_documents(knowledge_base_path): + print(' - Display Name: {}'.format(document.display_name)) + print(' - Knowledge ID: {}'.format(document.name)) + print(' - MIME Type: {}'.format(document.mime_type)) + print(' - Knowledge Types:') + for knowledge_type in document.knowledge_types: + print(' - {}'.format(KNOWLEDGE_TYPES[knowledge_type])) + print(' - Source: {}\n'.format(document.content_uri)) +# [END dialogflow_list_document] + + +# [START dialogflow_create_document]] +def create_document(project_id, knowledge_base_id, display_name, mime_type, + knowledge_type, content_uri): + """Creates a Document. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base. + display_name: The display name of the Document. + mime_type: The mime_type of the Document. e.g. text/csv, text/html, + text/plain, text/pdf etc. + knowledge_type: The Knowledge type of the Document. e.g. FAQ, + EXTRACTIVE_QA. + content_uri: Uri of the document, e.g. gs://path/mydoc.csv, + http://mypage.com/faq.html.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.DocumentsClient() + knowledge_base_path = client.knowledge_base_path(project_id, + knowledge_base_id) + + document = dialogflow.types.Document( + display_name=display_name, mime_type=mime_type, + content_uri=content_uri) + + document.knowledge_types.append( + dialogflow.types.Document.KnowledgeType.Value(knowledge_type)) + + response = client.create_document(knowledge_base_path, document) + print('Waiting for results...') + document = response.result(timeout=90) + print('Created Document:') + print(' - Display Name: {}'.format(document.display_name)) + print(' - Knowledge ID: {}'.format(document.name)) + print(' - MIME Type: {}'.format(document.mime_type)) + print(' - Knowledge Types:') + for knowledge_type in document.knowledge_types: + print(' - {}'.format(KNOWLEDGE_TYPES[knowledge_type])) + print(' - Source: {}\n'.format(document.content_uri)) +# [END dialogflow_create_document]] + + +# [START dialogflow_get_document]] +def get_document(project_id, knowledge_base_id, document_id): + """Gets a Document. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base. + document_id: Id of the Document.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.DocumentsClient() + document_path = client.document_path(project_id, knowledge_base_id, + document_id) + + response = client.get_document(document_path) + print('Got Document:') + print(' - Display Name: {}'.format(response.display_name)) + print(' - Knowledge ID: {}'.format(response.name)) + print(' - MIME Type: {}'.format(response.mime_type)) + print(' - Knowledge Types:') + for knowledge_type in response.knowledge_types: + print(' - {}'.format(KNOWLEDGE_TYPES[knowledge_type])) + print(' - Source: {}\n'.format(response.content_uri)) +# [END dialogflow_get_document]] + + +# [START dialogflow_delete_document]] +def delete_document(project_id, knowledge_base_id, document_id): + """Deletes a Document. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base. + document_id: Id of the Document.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.DocumentsClient() + document_path = client.document_path(project_id, knowledge_base_id, + document_id) + + response = client.delete_document(document_path) + print('operation running:\n {}'.format(response.operation)) + print('Waiting for results...') + print('Done.\n {}'.format(response.result())) +# [END dialogflow_delete_document]] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', help='Project id. Required.', required=True) + parser.add_argument( + '--knowledge-base-id', + help='The id of the Knowledge Base that the Document belongs to', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', + help='List all Documents that belong to a certain Knowledge base.') + + create_parser = subparsers.add_parser( + 'create', help='Create a Document for a certain Knowledge base.') + create_parser.add_argument( + '--display-name', + help='A name of the Document, mainly used for display purpose, ' + 'can not be used to identify the Document.', + default=str('')) + create_parser.add_argument( + '--mime-type', + help='The mime-type of the Document, e.g. text/csv, text/html, ' + 'text/plain, text/pdf etc. ', + required=True) + create_parser.add_argument( + '--knowledge-type', + help='The knowledge-type of the Document, e.g. FAQ, EXTRACTIVE_QA.', + required=True) + create_parser.add_argument( + '--content-uri', + help='The uri of the Document, e.g. gs://path/mydoc.csv, ' + 'http://mypage.com/faq.html', + required=True) + + get_parser = subparsers.add_parser( + 'get', help='Get a Document by its id and the Knowledge base id.') + get_parser.add_argument( + '--document-id', help='The id of the Document', required=True) + + delete_parser = subparsers.add_parser( + 'delete', help='Delete a Document by its id and the Knowledge base' + 'id.') + delete_parser.add_argument( + '--document-id', + help='The id of the Document you want to delete', + required=True) + + args = parser.parse_args() + + if args.command == 'list': + list_documents(args.project_id, args.knowledge_base_id) + elif args.command == 'create': + create_document(args.project_id, args.knowledge_base_id, + args.display_name, args.mime_type, args.knowledge_type, + args.content_uri) + elif args.command == 'get': + get_document(args.project_id, args.knowledge_base_id, args.document_id) + elif args.command == 'delete': + delete_document(args.project_id, args.knowledge_base_id, + args.document_id) diff --git a/dialogflow/entity_management.py b/dialogflow/entity_management.py new file mode 100644 index 000000000000..2fff2fe12fe0 --- /dev/null +++ b/dialogflow/entity_management.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Entity Python sample showing how to manage entities. + +Examples: + python entity_management.py -h + python entity_management.py --project-id PROJECT_ID \ + list --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a + python entity_management.py --project-id PROJECT_ID \ + create new_room --synonyms basement cellar \ + --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a + python entity_management.py --project-id PROJECT_ID \ + delete new_room \ + --entity-type-id e57238e2-e692-44ea-9216-6be1b2332e2a +""" + +import argparse + + +# [START dialogflow_list_entities] +def list_entities(project_id, entity_type_id): + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + parent = entity_types_client.entity_type_path( + project_id, entity_type_id) + + entities = entity_types_client.get_entity_type(parent).entities + + for entity in entities: + print('Entity value: {}'.format(entity.value)) + print('Entity synonyms: {}\n'.format(entity.synonyms)) +# [END dialogflow_list_entities] + + +# [START dialogflow_create_entity] +def create_entity(project_id, entity_type_id, entity_value, synonyms): + """Create an entity of the given entity type.""" + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + # Note: synonyms must be exactly [entity_value] if the + # entity_type's kind is KIND_LIST + synonyms = synonyms or [entity_value] + + entity_type_path = entity_types_client.entity_type_path( + project_id, entity_type_id) + + entity = dialogflow.types.EntityType.Entity() + entity.value = entity_value + entity.synonyms.extend(synonyms) + + response = entity_types_client.batch_create_entities( + entity_type_path, [entity]) + + print('Entity created: {}'.format(response)) +# [END dialogflow_create_entity] + + +# [START dialogflow_delete_entity] +def delete_entity(project_id, entity_type_id, entity_value): + """Delete entity with the given entity type and entity value.""" + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + entity_type_path = entity_types_client.entity_type_path( + project_id, entity_type_id) + + entity_types_client.batch_delete_entities( + entity_type_path, [entity_value]) +# [END dialogflow_delete_entity] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help=list_entities.__doc__) + list_parser.add_argument( + '--entity-type-id', + help='The id of the entity_type.') + + create_parser = subparsers.add_parser( + 'create', help=create_entity.__doc__) + create_parser.add_argument( + 'entity_value', + help='The entity value to be added.') + create_parser.add_argument( + '--entity-type-id', + help='The id of the entity_type to which to add an entity.', + required=True) + create_parser.add_argument( + '--synonyms', + nargs='*', + help='The synonyms that will map to the provided entity value.', + default=[]) + + delete_parser = subparsers.add_parser( + 'delete', help=delete_entity.__doc__) + delete_parser.add_argument( + '--entity-type-id', + help='The id of the entity_type.', + required=True) + delete_parser.add_argument( + 'entity_value', + help='The value of the entity to delete.') + + args = parser.parse_args() + + if args.command == 'list': + list_entities(args.project_id, args.entity_type_id) + elif args.command == 'create': + create_entity( + args.project_id, args.entity_type_id, args.entity_value, + args.synonyms) + elif args.command == 'delete': + delete_entity( + args.project_id, args.entity_type_id, args.entity_value) diff --git a/dialogflow/entity_management_test.py b/dialogflow/entity_management_test.py new file mode 100644 index 000000000000..e2433d7a4e9d --- /dev/null +++ b/dialogflow/entity_management_test.py @@ -0,0 +1,90 @@ +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +import entity_management +import entity_type_management + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +ENTITY_TYPE_DISPLAY_NAME = 'fake_entity_type_for_testing' +ENTITY_VALUE_1 = 'fake_entity_for_testing_1' +ENTITY_VALUE_2 = 'fake_entity_for_testing_2' +SYNONYMS = ['fake_synonym_for_testing_1', 'fake_synonym_for_testing_2'] + + +def test_create_entity_type(capsys): + entity_type_ids = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME) + + assert len(entity_type_ids) == 0 + + entity_type_management.create_entity_type( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME, 'KIND_MAP') + out, _ = capsys.readouterr() + + assert 'display_name: "{}"'.format(ENTITY_TYPE_DISPLAY_NAME) in out + + entity_type_ids = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME) + + assert len(entity_type_ids) == 1 + + +def test_create_entity(capsys): + entity_type_id = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME)[0] + + entity_management.create_entity( + PROJECT_ID, entity_type_id, ENTITY_VALUE_1, []) + entity_management.create_entity( + PROJECT_ID, entity_type_id, ENTITY_VALUE_2, SYNONYMS) + + entity_management.list_entities(PROJECT_ID, entity_type_id) + out, _ = capsys.readouterr() + + assert 'Entity value: {}'.format(ENTITY_VALUE_1) in out + assert 'Entity value: {}'.format(ENTITY_VALUE_2) in out + for synonym in SYNONYMS: + assert synonym in out + + +def test_delete_entity(capsys): + entity_type_id = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME)[0] + + entity_management.delete_entity( + PROJECT_ID, entity_type_id, ENTITY_VALUE_1) + entity_management.delete_entity( + PROJECT_ID, entity_type_id, ENTITY_VALUE_2) + + entity_management.list_entities(PROJECT_ID, entity_type_id) + out, _ = capsys.readouterr() + + assert out == '' + + +def test_delete_entity_type(capsys): + entity_type_ids = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME) + + for entity_type_id in entity_type_ids: + entity_type_management.delete_entity_type(PROJECT_ID, entity_type_id) + + entity_type_ids = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME) + + assert len(entity_type_ids) == 0 diff --git a/dialogflow/entity_type_management.py b/dialogflow/entity_type_management.py new file mode 100644 index 000000000000..1f342f3a1b94 --- /dev/null +++ b/dialogflow/entity_type_management.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API EntityType Python sample showing how to manage entity types. + +Examples: + python entity_type_management.py -h + python entity_type_management.py --project-id PROJECT_ID list + python entity_type_management.py --project-id PROJECT_ID create employee + python entity_type_management.py --project-id PROJECT_ID delete \ + e57238e2-e692-44ea-9216-6be1b2332e2a +""" + +import argparse + + +# [START dialogflow_list_entity_types] +def list_entity_types(project_id): + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + parent = entity_types_client.project_agent_path(project_id) + + entity_types = entity_types_client.list_entity_types(parent) + + for entity_type in entity_types: + print('Entity type name: {}'.format(entity_type.name)) + print('Entity type display name: {}'.format(entity_type.display_name)) + print('Number of entities: {}\n'.format(len(entity_type.entities))) +# [END dialogflow_list_entity_types] + + +# [START dialogflow_create_entity_type] +def create_entity_type(project_id, display_name, kind): + """Create an entity type with the given display name.""" + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + parent = entity_types_client.project_agent_path(project_id) + entity_type = dialogflow.types.EntityType( + display_name=display_name, kind=kind) + + response = entity_types_client.create_entity_type(parent, entity_type) + + print('Entity type created: \n{}'.format(response)) +# [END dialogflow_create_entity_type] + + +# [START dialogflow_delete_entity_type] +def delete_entity_type(project_id, entity_type_id): + """Delete entity type with the given entity type name.""" + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + entity_type_path = entity_types_client.entity_type_path( + project_id, entity_type_id) + + entity_types_client.delete_entity_type(entity_type_path) +# [END dialogflow_delete_entity_type] + + +# Helper to get entity_type_id from display name. +def _get_entity_type_ids(project_id, display_name): + import dialogflow_v2 as dialogflow + entity_types_client = dialogflow.EntityTypesClient() + + parent = entity_types_client.project_agent_path(project_id) + entity_types = entity_types_client.list_entity_types(parent) + entity_type_names = [ + entity_type.name for entity_type in entity_types + if entity_type.display_name == display_name] + + entity_type_ids = [ + entity_type_name.split('/')[-1] for entity_type_name + in entity_type_names] + + return entity_type_ids + + +if __name__ == '__main__': + import dialogflow_v2 + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help=list_entity_types.__doc__) + + create_parser = subparsers.add_parser( + 'create', help=create_entity_type.__doc__) + create_parser.add_argument( + 'display_name', + help='The display name of the entity.') + create_parser.add_argument( + '--kind', + help='The kind of entity. KIND_MAP (default) or KIND_LIST.', + default=dialogflow_v2.enums.EntityType.Kind.KIND_MAP) + + delete_parser = subparsers.add_parser( + 'delete', help=delete_entity_type.__doc__) + delete_parser.add_argument( + 'entity_type_id', + help='The id of the entity_type.') + + args = parser.parse_args() + + if args.command == 'list': + list_entity_types(args.project_id) + elif args.command == 'create': + create_entity_type(args.project_id, args.display_name, args.kind) + elif args.command == 'delete': + delete_entity_type(args.project_id, args.entity_type_id) diff --git a/dialogflow/intent_management.py b/dialogflow/intent_management.py new file mode 100644 index 000000000000..853e191c1a18 --- /dev/null +++ b/dialogflow/intent_management.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API Intent Python sample showing how to manage intents. + +Examples: + python intent_management.py -h + python intent_management.py --project-id PROJECT_ID list + python intent_management.py --project-id PROJECT_ID create \ + "room.cancellation - yes" \ + --training-phrases-parts "cancel" "cancellation" \ + --message-texts "Are you sure you want to cancel?" "Cancelled." + python intent_management.py --project-id PROJECT_ID delete \ + 74892d81-7901-496a-bb0a-c769eda5180e +""" + +import argparse + + +# [START dialogflow_list_intents] +def list_intents(project_id): + import dialogflow_v2 as dialogflow + intents_client = dialogflow.IntentsClient() + + parent = intents_client.project_agent_path(project_id) + + intents = intents_client.list_intents(parent) + + for intent in intents: + print('=' * 20) + print('Intent name: {}'.format(intent.name)) + print('Intent display_name: {}'.format(intent.display_name)) + print('Action: {}\n'.format(intent.action)) + print('Root followup intent: {}'.format( + intent.root_followup_intent_name)) + print('Parent followup intent: {}\n'.format( + intent.parent_followup_intent_name)) + + print('Input contexts:') + for input_context_name in intent.input_context_names: + print('\tName: {}'.format(input_context_name)) + + print('Output contexts:') + for output_context in intent.output_contexts: + print('\tName: {}'.format(output_context.name)) +# [END dialogflow_list_intents] + + +# [START dialogflow_create_intent] +def create_intent(project_id, display_name, training_phrases_parts, + message_texts): + """Create an intent of the given intent type.""" + import dialogflow_v2 as dialogflow + intents_client = dialogflow.IntentsClient() + + parent = intents_client.project_agent_path(project_id) + training_phrases = [] + for training_phrases_part in training_phrases_parts: + part = dialogflow.types.Intent.TrainingPhrase.Part( + text=training_phrases_part) + # Here we create a new training phrase for each provided part. + training_phrase = dialogflow.types.Intent.TrainingPhrase(parts=[part]) + training_phrases.append(training_phrase) + + text = dialogflow.types.Intent.Message.Text(text=message_texts) + message = dialogflow.types.Intent.Message(text=text) + + intent = dialogflow.types.Intent( + display_name=display_name, + training_phrases=training_phrases, + messages=[message]) + + response = intents_client.create_intent(parent, intent) + + print('Intent created: {}'.format(response)) +# [END dialogflow_create_intent] + + +# [START dialogflow_delete_intent] +def delete_intent(project_id, intent_id): + """Delete intent with the given intent type and intent value.""" + import dialogflow_v2 as dialogflow + intents_client = dialogflow.IntentsClient() + + intent_path = intents_client.intent_path(project_id, intent_id) + + intents_client.delete_intent(intent_path) +# [END dialogflow_delete_intent] + + +# Helper to get intent from display name. +def _get_intent_ids(project_id, display_name): + import dialogflow_v2 as dialogflow + intents_client = dialogflow.IntentsClient() + + parent = intents_client.project_agent_path(project_id) + intents = intents_client.list_intents(parent) + intent_names = [ + intent.name for intent in intents + if intent.display_name == display_name] + + intent_ids = [ + intent_name.split('/')[-1] for intent_name + in intent_names] + + return intent_ids + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help=list_intents.__doc__) + + create_parser = subparsers.add_parser( + 'create', help=create_intent.__doc__) + create_parser.add_argument( + 'display_name') + create_parser.add_argument( + '--training-phrases-parts', + nargs='*', + type=str, + help='Training phrases.', + default=[]) + create_parser.add_argument( + '--message-texts', + nargs='*', + type=str, + help='Message texts for the agent\'s response when the intent ' + 'is detected.', + default=[]) + + delete_parser = subparsers.add_parser( + 'delete', help=delete_intent.__doc__) + delete_parser.add_argument( + 'intent_id', + help='The id of the intent.') + + args = parser.parse_args() + + if args.command == 'list': + list_intents(args.project_id) + elif args.command == 'create': + create_intent( + args.project_id, args.display_name, args.training_phrases_parts, + args.message_texts, ) + elif args.command == 'delete': + delete_intent(args.project_id, args.intent_id) diff --git a/dialogflow/intent_management_test.py b/dialogflow/intent_management_test.py new file mode 100644 index 000000000000..53105fe0002a --- /dev/null +++ b/dialogflow/intent_management_test.py @@ -0,0 +1,68 @@ +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +import intent_management + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +INTENT_DISPLAY_NAME = 'fake_display_name_for_testing' +MESSAGE_TEXTS = [ + 'fake_message_text_for_testing_1', + 'fake_message_text_for_testing_2' +] +TRAINING_PHRASE_PARTS = [ + 'fake_training_phrase_part_1', + 'fake_training_phease_part_2' +] + + +def test_create_intent(capsys): + intent_management.create_intent( + PROJECT_ID, INTENT_DISPLAY_NAME, TRAINING_PHRASE_PARTS, + MESSAGE_TEXTS) + + intent_ids = intent_management._get_intent_ids( + PROJECT_ID, INTENT_DISPLAY_NAME) + + assert len(intent_ids) == 1 + + intent_management.list_intents(PROJECT_ID) + + out, _ = capsys.readouterr() + + assert INTENT_DISPLAY_NAME in out + + for message_text in MESSAGE_TEXTS: + assert message_text in out + + +def test_delete_session_entity_type(capsys): + intent_ids = intent_management._get_intent_ids( + PROJECT_ID, INTENT_DISPLAY_NAME) + + for intent_id in intent_ids: + intent_management.delete_intent(PROJECT_ID, intent_id) + + intent_management.list_intents(PROJECT_ID) + out, _ = capsys.readouterr() + + assert INTENT_DISPLAY_NAME not in out + + intent_ids = intent_management._get_intent_ids( + PROJECT_ID, INTENT_DISPLAY_NAME) + + assert len(intent_ids) == 0 diff --git a/dialogflow/knowledge_base_management.py b/dialogflow/knowledge_base_management.py new file mode 100644 index 000000000000..b5ceab786ccf --- /dev/null +++ b/dialogflow/knowledge_base_management.py @@ -0,0 +1,153 @@ +#!/usr/bin/env python + +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Dialogflow API Python sample showing how to manage Knowledge bases. + +Examples: + python knowledge_base_management.py -h + python knowledge_base_management.py --project-id PROJECT_ID \ + list + python knowledge_base_management.py --project-id PROJECT_ID \ + create --display-name DISPLAY_NAME + python knowledge_base_management.py --project-id PROJECT_ID \ + get --knowledge-base-id knowledge_base_id + python knowledge_base_management.py --project-id PROJECT_ID \ + delete --knowledge-base-id knowledge_base_id +""" + +import argparse + + +# [START dialogflow_list_knowledge_base] +def list_knowledge_bases(project_id): + """Lists the Knowledge bases belonging to a project. + + Args: + project_id: The GCP project linked with the agent.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.KnowledgeBasesClient() + project_path = client.project_path(project_id) + + print('Knowledge Bases for: {}'.format(project_id)) + for knowledge_base in client.list_knowledge_bases(project_path): + print(' - Display Name: {}'.format(knowledge_base.display_name)) + print(' - Knowledge ID: {}\n'.format(knowledge_base.name)) +# [END dialogflow_list_knowledge_base] + + +# [START dialogflow_create_knowledge_base] +def create_knowledge_base(project_id, display_name): + """Creates a Knowledge base. + + Args: + project_id: The GCP project linked with the agent. + display_name: The display name of the Knowledge base.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.KnowledgeBasesClient() + project_path = client.project_path(project_id) + + knowledge_base = dialogflow.types.KnowledgeBase( + display_name=display_name) + + response = client.create_knowledge_base(project_path, knowledge_base) + + print('Knowledge Base created:\n') + print('Display Name: {}\n'.format(response.display_name)) + print('Knowledge ID: {}\n'.format(response.name)) +# [END dialogflow_create_knowledge_base] + + +# [START dialogflow_get_knowledge_base] +def get_knowledge_base(project_id, knowledge_base_id): + """Gets a specific Knowledge base. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.KnowledgeBasesClient() + knowledge_base_path = client.knowledge_base_path( + project_id, knowledge_base_id) + + response = client.get_knowledge_base(knowledge_base_path) + + print('Got Knowledge Base:') + print(' - Display Name: {}'.format(response.display_name)) + print(' - Knowledge ID: {}'.format(response.name)) +# [END dialogflow_get_knowledge_base] + + +# [START dialogflow_delete_knowledge_base] +def delete_knowledge_base(project_id, knowledge_base_id): + """Deletes a specific Knowledge base. + + Args: + project_id: The GCP project linked with the agent. + knowledge_base_id: Id of the Knowledge base.""" + import dialogflow_v2beta1 as dialogflow + client = dialogflow.KnowledgeBasesClient() + knowledge_base_path = client.knowledge_base_path( + project_id, knowledge_base_id) + + response = client.delete_knowledge_base(knowledge_base_path) + + print('Knowledge Base deleted.'.format(response)) +# [END dialogflow_delete_knowledge_base] + + +if __name__ == '__main__': + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', help='Project/agent id.', required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help='List all Knowledge bases that belong to the project.') + + create_parser = subparsers.add_parser( + 'create', help='Create a new Knowledge base.') + create_parser.add_argument( + '--display-name', + help='A name of the Knowledge base, used for display purpose, ' + 'can not be used to identify the Knowledge base.', + default=str('')) + + get_parser = subparsers.add_parser( + 'get', help='Get a Knowledge base by its id.') + get_parser.add_argument( + '--knowledge-base-id', help='The id of the Knowledge base.', + required=True) + + delete_parser = subparsers.add_parser( + 'delete', help='Delete a Knowledge base by its id.') + delete_parser.add_argument( + '--knowledge-base-id', + help='The id of the Knowledge base you want to delete.', + required=True) + + args = parser.parse_args() + + if args.command == 'list': + list_knowledge_bases(args.project_id) + elif args.command == 'create': + create_knowledge_base(args.project_id, args.display_name) + elif args.command == 'get': + get_knowledge_base(args.project_id, args.knowledge_base_id) + elif args.command == 'delete': + delete_knowledge_base(args.project_id, args.knowledge_base_id) diff --git a/dialogflow/knowledge_base_management_test.py b/dialogflow/knowledge_base_management_test.py new file mode 100644 index 000000000000..d5e6f26cf31e --- /dev/null +++ b/dialogflow/knowledge_base_management_test.py @@ -0,0 +1,107 @@ +# Copyright 2018 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +import detect_intent_knowledge +import document_management +import knowledge_base_management + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +TEXTS = ['Where is my data stored?'] + +KNOWLEDGE_BASE_NAME = 'fake_knowledge_base_name' +DOCUMENT_BASE_NAME = 'fake_document_name' + + +def test_create_knowledge_base(capsys): + # Check the knowledge base does not yet exists + knowledge_base_management.list_knowledge_bases(PROJECT_ID) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(KNOWLEDGE_BASE_NAME) not in out + + # Create a knowledge base + knowledge_base_management.create_knowledge_base(PROJECT_ID, + KNOWLEDGE_BASE_NAME) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(KNOWLEDGE_BASE_NAME) in out + + # List the knowledge base + knowledge_base_management.list_knowledge_bases(PROJECT_ID) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(KNOWLEDGE_BASE_NAME) in out + + knowledge_base_id = out.split('knowledgeBases/')[1].rstrip() + + # Get the knowledge base + knowledge_base_management.get_knowledge_base(PROJECT_ID, knowledge_base_id) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(KNOWLEDGE_BASE_NAME) in out + + # Create a Document + document_management.create_document( + PROJECT_ID, knowledge_base_id, DOCUMENT_BASE_NAME, 'text/html', 'FAQ', + 'https://cloud.google.com/storage/docs/faq') + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(DOCUMENT_BASE_NAME) in out + + # List the Document + document_management.list_documents(PROJECT_ID, knowledge_base_id) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(DOCUMENT_BASE_NAME) in out + + document_id = out.split('documents/')[1].split(' - MIME Type:')[0].rstrip() + + # Get the Document + document_management.get_document(PROJECT_ID, knowledge_base_id, + document_id) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(DOCUMENT_BASE_NAME) in out + + # Detect intent with Knowledge Base + detect_intent_knowledge.detect_intent_knowledge( + PROJECT_ID, SESSION_ID, 'en-us', knowledge_base_id, TEXTS) + + out, _ = capsys.readouterr() + assert 'Knowledge results' in out + + # Delete the Document + document_management.delete_document(PROJECT_ID, knowledge_base_id, + document_id) + + # List the Document + document_management.list_documents(PROJECT_ID, knowledge_base_id) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(DOCUMENT_BASE_NAME) not in out + + # Delete the Knowledge Base + knowledge_base_management.delete_knowledge_base(PROJECT_ID, + knowledge_base_id) + + # List the knowledge base + knowledge_base_management.list_knowledge_bases(PROJECT_ID) + + out, _ = capsys.readouterr() + assert 'Display Name: {}'.format(KNOWLEDGE_BASE_NAME) not in out diff --git a/dialogflow/requirements.txt b/dialogflow/requirements.txt new file mode 100644 index 000000000000..6b1de5689d25 --- /dev/null +++ b/dialogflow/requirements.txt @@ -0,0 +1 @@ +dialogflow==0.5.1 diff --git a/dialogflow/resources/230pm.wav b/dialogflow/resources/230pm.wav new file mode 100644 index 0000000000000000000000000000000000000000..7509eca784dcac25dba40658f656eeba26d62031 GIT binary patch literal 55072 zcmeEug?AK5)NfVGXx!bMK!V#Mi@UqKyTbyD%i_M+0*kx5J1hheAjI91k&MrDcU8U0 ze&72e-g!HHDw)ZtuD*5W*7aWobnnu|F9U#~zYggNViAEB*Z6>pu?s$ASMi@E-^MTksao|4={KtX+IPf0_{^P)Z9Qc2V1Cz!t z8Xxxl|0$CHC6_lCTf}s}#JdgvHUL5@!O9vu^V1noXpl+~q76)W>mg0Yh?B92F za{(YkB6fN?h)9Q>2=sH^{e&?8t|_BG<@9d$-%*zhse1yZv+Cws{+(ZUPu-|n@BdO& zM^W7i(Rl)$S$Em~orUPib@S>dl2Ph;N*zlnty{Hju0U6{P)e--(k1>&&;P8-QM&6c zCA}2%uDYv^7j-+Z{X4Amw~amt(Yr8xPTlJK|30a1ZXHL2|9wi`lf-{_`aj&O<4zrC zl>d9z|4?4XnL7Hd#Q5*pR=P__cLnHdXP~0PiQc28zn%Zx2LN?ktfQjt4%5FospDx2}QGQA5f}6}_jHnCV{XD5;~v9eDpslN+6{q-#L> zEQzjbqSV((fR$*-1L6hlg2rGVxC%SL9Krz=l*3SP82H1cumr@zxy*U^D_PEWbzY`^ zAm(lp$T|1dzRS%j)2MV1k)Onk~o<+jKy!@XPFEB8(HBY@Sg324d@p0 zh^a=ma0g1?Wd5BshO||Q;!i0@n#?sN4aivWmc%t$X_S#^Ai`DMjK>bR=<~!exYX4I9QH^&SaNs zKvYX>*m|OmH&yK)8d86|2y%wu`Wk zAI6Mv^cUX9R;v~o`h(Z9Rp2mwZCdO6L|LfAXraq^>oe3(W|ltS5wJJ>=9oklD8g}w zshiA69ZNjTYSi3)0=#Wl#{BBx0$K2sJeWcIDVs??KZAeeKL{2hz=bhgS7#?L0j<~RIQaVWsDxt0~6vwSEH zcc{Q}b~pMc4&?5!r)@87XQ(WcJBZXl)>`$+;g3C?x-mzYDPmXoMs5!I3;z&0GRV{$ zxhSubbm@WpyS+KTggImWif6hh*Il^G9+7{= zci7+MU7Xe!PKl3|BgtH;rBI{@Q&gA-+4o5Kz}3~o)Yml8w+IJRy?1PvO<)8EvYus* z$`-(PAk^?hvD3>*JIBVUl`eu=rl0Q7P_^CM*74D0zf9#YvD0BA5UFlpX|JE=W@CNK zxVDCPIp^uG8W-@HiY44b69@09=OI^N1pi7soOxmm}ckDm`5TNC7Om$3272!s4 zr&6IfWyFwkYKODXYR1S$P&zxqPwWlSnD5K>WA4c@9DpR&jf}7lfWI)a(FR*5`!g}q z-rv>}=YaRX?pT3%`5a-M_!jMh57=P%kfh*5uPHOMKu#IUu!we z7m-wpRd~*HkslU2!YJXLgJ;?!6DgA<<_Nn8&vLv&7SK{SAjHVV%g!B$Fw@WbD8If7%=JCiyVMTl*yOiqfC$XX|I1 z&fioQ%Dy;ag$XXv`~dS=X`6h8Qx#Y4=z#KMr=`KxJMb@llπ%K8dyVNXJ>W2xw( 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 X0@kMgGK>B{Z3zDQfB*e2KY{-Tu9b4j literal 0 HcmV?d00001 diff --git a/dialogflow/resources/RoomReservation.zip b/dialogflow/resources/RoomReservation.zip new file mode 100644 index 0000000000000000000000000000000000000000..7873fb628c895e7510bac677d0ad35820759094d GIT binary patch literal 10922 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 Nh$0A1lK;Pd{tuoqdJX^p literal 0 HcmV?d00001 diff --git a/dialogflow/resources/half_an_hour.wav b/dialogflow/resources/half_an_hour.wav new file mode 100644 index 0000000000000000000000000000000000000000..71010a871bbbf953d040acf6ba5979e928865512 GIT binary patch literal 36154 zcmeEt1$P@s({&Gv*)nr%2b{!VW@cv21~#-|+%PjUGc(hM9Cn;S(ZG~-07~mx9ZmLe!Y7)-v_{$Zlin6TCgli0RTYw`^L`vFY5q6fdcd%IB@tc zIsg2BxBnsVKLq}V!2b~V9|HeF;C~4G4}t$7@IM6phrs_3_#XoQL*V}_1ZGTIHmyCc z@Be?e5kL$?Kmah{hF&NHkst~1A{OQ9V`^OX%6ih&&}ffAUY8~)!hKS2u2=8qErI)QdPI7a>x zt6&cN3=hNI{C}GG&k_SEfA0m(0w;I``hr2g2OsdCUk6XYW>5(0!4~iXJPwM$7jO?8 z1FOI`aEE`_Uf2niacjBmup77l3PBcl4Q7F0{(CHhcCH;PgAc)epam;|8(apPpqu*} zPKSEV&$WaZ+%oPy_Z{9wLa_{VD6)t@PaQl2U%?*00Vi`BHi(-7Mj>sHlW-{;&JJc9 z!D6Hw)uS(wDaaq>5mJIgqj9JR%wU(Z`(R7d1&Y}cwih>^o5alq$!Hc>!Oh_|K|kn( zhN5Y3H#ZJ`L%QS52sP0LJ<4roWn2&VlDo_7Wk$1$nHbtcA7x{>(Od#-jb6mp5|HRg zjwJuW8iMAqHQdN1+^>{fo?n4ps&jBnml> zh>_h8g@Md`CK(Jxg~)iA4`kSLY$7_CJ?_i#E~THa7a>NR#AiX0djPi}o48o!7CeKl z#>V21`d9Q8Z^)K-MeYTzJZ6kwp7b)&+gspkiXJ8xi>j&f_*~|PrL8TK^@|Ql`vSYm zN13PJ{O*^Ae21+A~oOt#>SWNqJoM3A1vS z=(j#Cn}nwmPw5+$Q^xhq2(&;_p%ltL6XReSqLPjeSSqhW!@WCfh1PRUv+pZo^sn}Y z&<)UTWGQAqWXKpe2)dY?^mW(`J%pTtk>DD725X3=aRdCXz3co_*?ZhM>SGaGpI#HH%fn*tW&^y)9-f`6PhF%7TVlCiBXJ=Ou zdQi?Prjy^{B__>xhVG0WB1gcf_Cdxewo%+dQLOTUQd57f~*q7i{=tJaFi$9bJzEW`9$;=^uh)+ZuWhZbX_nrlU67BBL-|EGffz9Dkn2Rim?iS>sx1C>|LYROh zVH>bj+*996r_dimeIl9=zo!hc;@>I^l-eBL@v83IUt%rZHEhy6~Ytv zaNi5ZU-nn7>3+udjKA2f=k*dVqGeb)2Ux1Nh;A2LClf#1{P zxyi^VRT6uo zO6hCyBasUp^{|#iXJb57ct@MHa`7Mm-6Gg0 zXhff|Hgms6Rb)6mh8gH==MdQj`NfjMs>cekIGe0bwWG!hMhZ3v^qkgwzgBGj;`_?Z z0t1L-fsxut9wG;lB#U{i-Xu>joxxn9Pr_O(U63u-%lApYVlTOoUbPFlCb}1T9{b$% zBW5K~;ut!ax$ddQd;$pBUHnpXO59p-0T%JWwZ^^2*B4$vO1aVO8afWNlRZ>EQht*t zK_g#3#}$u+6W|^yi5=~3W0`GtBJD&2G{@xWcqur=y@j)20Qb~Z9t*duLE^rR11XW50cUeqq+xkf5h zF(Jmzre+?RYYZ=9VnI{n7o3fDL06D%MF*(|SRnBpcf)~T4wp+G;?~j~ou!sF)+?_5 z=xo)!fY!=+ijH`F&m>!)y4t!+E-#`cva!eTiqFCPg&xB`k^Lkt*%q`^>0?`QV@JReSzHm&*zRy9N$WUQzBBeMWk6sg{8it4mLpDC%|~KP7)u?WF7R zK;%918eL7a#ivmpvA(?2B=9qUPs0OO_fz1^=z4p2Y{a)Q7dx^gzY9K7wS1MoHUh_V1Zs29P6In-h_I`8^^KEeY z&GSrq4L{5aeGAc};cV$Obopn za8>k$IpMlwQ`NTDpV6n(t?;1eQoND)tz^1%hE^HWRlS$0WA?er9EY8Wt~<`X#?4hv zbw3?*v0Ckb$j_m(wRdIjgqy%VCe>47X=Q8VX~kstZQdTNome9^${NcW6AkG*zC8Mq zf2{ws*YDcP?jb4ZN9kdz8XJaO;ItCe$+ zuNulg9@hrlBD$mL9n?GEtavGS>^|e{={oKD%hT4qkUK4Ht*HsXB+r;m_V4;i!&|e% zq4U;(5#)67qrmBbALM2{i|Y*65DR1jUD!~~P3aZ+4|%Hcbnv3kmtn6%w+5frR?E+cx?v=H!T-}`cHg6WfkHF{ zYl@s;HgiL{vwS4GHF$UwLR(<8P4n5>KD`u*LAKtSnI2vT{*e3U)kEq z={iI=vu>>}yJko6-v!-DrxqR4ht%EGztlf0{7`tkGD0`Ve8M@wzD$=?Hafpc0bR7E z_VxhG%r7+uU5rpAEQ{?Ks|-CY-h+|8d%i3vLElnOMZcx5G>ap}Nqt*& zYi?__qu#OD9nlw~zs4R8F-t_`LSl*JQ~( zxL!0yZj>#PoD%_Yf5}|M@_+>OT4lGOX)*sch;4X0!4&&7v|K9qAku9o6 zDyUo1N=?tm`|%6oo<(H`r7Kd!pM-yj5m|*YF^~)E9a9jS5%VWvMPQ2JtN4lFD3wZ# z1TFl}ou}*%oEQAB&`Wqvq@26wC%oIdalT2uJS5UGqQYJj>{oaX(QF@Ll z`)hHTdu!yRHmYuyJARM9sOb+2ooifv`z_ab*HcFUQ;Ahkcje8si4kKG);4|A($x%Y zI3WD0WGgu8EAz8lBP?C)R79%NwdFx;f3&BzK09^Q<kQ@yP=yf#F4yqcx{Ro3=s)Ou;<(c=iin#h7N{4mT|sQXiuR^ zHdgsCFeNIw{^-QT4SGc$RQ)4(jl6DwbIOMMWk#vtyV+`-ZJKN@wf^zC*(P{X z@l&NO@^_=dEnBwf(_oP{0z2mHWEI<^y$Wc-I*}^`og~r9M9uGj9~z51SR6~0WBri| zP!0kRfLDp;1`LYIseiEXghpsRQRqI!Nx@2_GxOee-80rR&r{!v`X{p|k$d=c5+@(w z&*606P-m36kMSR4vgx(OYr0?8S@)^pLHYH{6#WR3$THqMR@b@gQ%T$WyZO%xe->`3 zNUI9f;k6z08!NvSY)@-a^wl{~BkJ67$c}-FJKYR@38c2SI=3;@oN3%@cAC4pe$p$! z1c6MJAAF^LX!CdN7BusRKNR+JZ!!%v?Xd^Y09#C55E{kLWTTXCRNd4b#YpKrK>=pw zSb9EVV)L*RNy|VyN)g|t!MFMg6DGw5go)GxsU7r5m(MBlwDu?aFZ=t@p=>XNA`+-} z0s~HfT0ia{=XhXyY+>qXgVgX%e^S3d*Sb2j(xIPed~Cc>*Ri~BX;g7$k+JG)MP8+^ z>SyJ_YEAWq^5BBtjL9V*eD_03+kfm6+GAu=o`z-z+K<&9)D6{dF+`ciJ3YSPoC8&h zj;Nv{1~(knv}@xBu|&W-!sYMcwRn5e{kbC87?t8QIZae0*)QLrsFpPqCkb4{f2bN6 ziuA>PQaxn91IC3;k7yj-w_adfb==!ozo>=TqR?jNFQhcTCVbw3wM^7TMSZI}gQhL?r zL#pasY52Yo5;tDkoh?~Ok3uCR+7i(S1vE4+QZ>wSrAGwhMzqIjJs zl*|L${ezq*jLWNAl>IDLR`k?&F>iOE&Uo8B;|RU4sz+&fKAC~0Ey&!J-=Ta+)j(Z} zu4PqO#RG$oyAgD;Y2R+O-7{LQ4c!9@O{*(jmu#*$p?_*Q?q17`!P2M_;aAyiRceqn zrYeDM;EIb5!9*|pM{O#b-+sfRWa@F1U>Tk$Tq-e1bYijivM5>DL)1kH$X+H2J(Dh8Cq6~yE(${C&Q%G75Xb5`XZD=4bE z;N2J0x7D-WBL@Zd2xwfcO!Ia(j4#Cs|1NG;9#WHHn&Z~6B0Nd9Ke$CbZ{n$DznetI z1qZzn#X#Ub86{EmCf+NEEg3V+HbR|8|^~BV? zrdxTVvZmE1>LM(ct&Dkg-F}0sW<&MH3Tg4P{6E=EvW!^^vWMhu$(^0^rzpZQOJ-== zwNJ$`bbz{5Qt)K9UG1V0SMIm`)g`G_iRKE=32qubTskChTy$B(=}Bo#*2Px^lafa; z!*#}f({8tSa5eXyXQm=<;;C@DXqH$cE#uE2S@K>Ym!gs@k}0wVvQN_4(ngBaf!{)} z@@HcTTC5I{H5BwEm*RI3iap})WSeOn==|<`f<#iksA1$TVh;M7p*7j$7dO|_`Bb-}vqp_v=AujgFMy`LMDc{n?^rZryOU|XMuqluAs zI}eIkjh(NHE8dhDk;UX6sc@LH{W-`!B1{5R%|hkzy&Jb{GPXfnM2!3fcd7 z5j7|CiC1`Qv?X`nD{?k+G;?3}cR+@banbBaF{Jwm(?$Es3-Q|hfr3~ti3;r+;!imAvWXSn&ev86fGk><+> z<4LKgm3WJ=lxip#A@m7b3KkISu+7*v^0VlObi6{KmIPNs-;5K+JqdrHSVi?kE0Aw^ zQ(`cd0i;}GCY}+p7r4Jc7YrdPaSk=o_Z)9c^$bdVo^FHwr*V(9k?U{Yc;90eYI|R6 zub5ogx5$*cFn3l4krtA5J@aPnz*3bi*d44?H5t^)G_+5@?=8D)i+uw9fD%FR@!}q( zd#W-G|2T$lAIT+(-@%(=jyC+zl7H+Zw@$ouVyr zM0G()$p?w&P``)|#8~ns^;Ixkv|n~bWeaK+JuUWgbV8U!wLvtPScBQH706w7ug~pi z>c7T~!c(a@QKG~x$&`E-GysY2r^bo8fi)S`zp4b)?`rnzd)7sn@0+gG9W|8JOsl?9 zK^H3vcI9lz8l1H|r$b(JK~cpkTO&bM?5Wm|dt~&sw3$}VA!*~PtPU?+ox7~?KzWZ^ zkMlMsA(ul-p70^&a8RN65E$o6c71Vu_h3vFJb=C@gGEmzURk0%UqXp$ zDIvL>$RRcnlZZjY9`cajv#6)^j7+Th9uga4OW0MvI6|cENj7E|`44)Rco5Hb?;EB+ z@-LZ3bs`z;1hN|BA*axVu)sIo-rumiBB?B}d`BM);wK50T%)Qv=FmK|~76`qjS8{^3k_t`-@JPo;u| ztp)#(kFZtfacnI18ZC#({$%F?JB$9)$zmPtNfUmIE7oCu7l^vFMR@DY|k4TB^8FexEtzwZd0%my}&PwN2PXoFM zHxUdXV@3BxFU2f%1KkRf>E3>UU+-}{bQYD#Wf-NG=$GiD4XmM0-NM?^+86_@*jer= zj4FsIz_Lf>WMusPd-LxP>FrC@=66VKU{XSIlRYg&?a#HU-#{8jAjzf{#mV{SN?+DY zw&*-n+&E&AtVeLu$X8KAqt=C+1AD0Aq$Fuz;@yWG!(1s79|KqtO)X9C3-N6+RXZmZhkk2i*<37`7~QS>SkOuBbUSh8f~*rThp=L%Z@LW7N(iC%?*@ckl~!+pV~2X-D+*MP4w3* zx|O#oJXg>!zbI>5PD*<3-&cNXGw+o>w+<(Mg{0U2tLdGV+uBcUIVYi)<}mk9ov(0c z!N{_Sy5AOoHyB!or}7ygO(Lrz|3n-O?WY}}R7($%f7qX%&U|&E1$`L#i)txuFZ(6$ zuGpzKAfGH#OBxIRrY_-c(S_(-jKNmpTZpmL8BvUUyQV=%8rgTg#{T?a^{wt(zUZDcv!L{Y)n(ltQs@|nk2 ztKHdL7};DhMKMoZs0r7Il!K+gqU${VMhmCkql9fXoDAEiFjAy09iqe z7dk~3B~lY#Zk* z(=p?8>s$9Snq+o)DQ9ErN8>GnR^PZrUR7THsC-LB&kBauR5=B~c}Q+yUS*y>cY4m- z%+&OS8N-SXTILa{;VoNS=(fIBMMr&;h2hI^jcs2=vx4-ZTa~R$>%0%y?)W89wPILk zalM!ZRSj%$+K3M7C4vy3@IQAgaK3XM^2pd0*m;3dd{`PH>mvWESgU@f5osEzQxsig zcg5d@Db!s)2lpUwDo=1u)KTQ74&c|27vLkXfpee-d<&0baXfcsE+IGTJ0+PEZY}bgzcGW zh@p|rP(7$xT@zK4p?_hBtyx;}rijhTP7|i){k-@4%AdIzPqR*CaYZpTE=LFXip2Z9 z9m5w6fjzD@>LyIGt|;u1aWOlf5Z9~RkCBnG8!Ds55ttHqG^8qGaI`mC8eXO zwn-*yt;e$0H<@^-5O}+Dstc$LkTd}A*%(T$c7_6Z(B;6G)0zgPfczJAGe0bc0C}UuE z=^8}t>*Aj4TI6X>KLuZ@YUzH}_JDT*@6;z1VxKl2|LaD_JYw zuec?HnMEAEVY*L zRqDr1wHtTWbK$N?zK$7g1D2e+eulW38I|htyb`)3x$JO7hw95!&&r0CyeXVfkXm@W zgskdjXkF(vML1v6z2)-8q1{}A>3+JlBjR1s-jH-tCXE5Fx>dE$*wtNysw54S?E*!i zc~Mmj)lCmH>6Oqs=&>-A`P&h1lUV}o*F9(1CgeOxH^qB}Pkf3psISabC_vSZLTg%zrYYymtqX4b=Gw-7S%R1?W;Xd zJJ0ml!ZP6@A6jqiKV$gn0r4F#L=7kTJZnfUpUPJ!vuYQ)on)Z8TVTUbTkwF8myyBo zuNwRlKRcp_T8IDVRoQyi9@mY~W2Qh)19XXWOMqRQqkbXVBbbYCMWfKR*l=tGkJolI z1ng(zH0!hbp0exEbTUogpe_;;WGR#4i}F;vn|PJ}OjZKEARmxrFoS)`9AxeAIT}W+ z;C&LI*m5KaWU>FU_m~TeiE9O#<4egJ!94LPu|;xHJWUiR*ns!OyI?igL$Wm=*)Eee z2_4V$?gJ5Q1Ezo&NH=MUUp&wF{6zw&Ynl6evqEVEEs37MFCJ7e` z3JDth0T-|x=)1nQzRCWTYyxr=zd_{V>k%ij+&|1qd;9rG#>3`uDR3M}28Y0Lh;w<& zE@lE-1>2y(_))wRZHO%6SSF2eGCWU!4e({uB;i}>L2-?!ldvh#h(~ZHN%KFu;=_?t zn8+@p>(ht)3)u(Y6h@OlR4*bPJI=dhmVsZOI|9Hp?kcl}-c9eP`_j?=bzYHcvF(Yu ziE&9?B;Q?jIA3^;{!R2W|4gsfHN#=DG%~%aP1EP{J&i>3GJCOei=)`q+sxE8t?N{m zW87=;*-qMyTAx@C+QvJ4^d50p#O;G>D1z=g4YOBsh5&L(me4vK>=}< zh$Tl*?Wu2MXL26#kVqmB>;bH$wLXzIi9cHoEW<}YR%Gl$v4RI?+w z^;};rgkP(Vm{{%=9E3QL8OSjphbOp=9Dp0ZPjnF8k@_ZXC~chW2p|gY~KDsUf9ucJ(eNMRgA^Y&N9})oXs|rY&D3Gz$us zbmyMg40XNgmRrWSnsB}FmBay}KJ`l6M)hCt?uhP@RK&^P<^fvOR@p>hXC#A8^GtPr z^C55uK8t)wEaMq}KGF{xhNt2`@rif@9!OpnED_xoJ|gE}ErA41;yq(~K{9O4wPA~y zB`n2#VsA39{O^66{2Q6C+;or)8i8C`4ep}`{3lsLPAA6@g?Je*Aj)tn_8A?3uELLz zBgG44Bjs=9b0zgfhl#Doc{bPw-OpUVJ)!=cYz#kXXNGq5?=K{Cc zz1Vxpf6&*(_r*2cUS<)Sr&vYS3)VcV)Y{87&U)6q!Wrkxa2D7%+0J>RakacKaA%}4 zE<5^6cw}gopxc@nnNBbTy$Ph~H&j7>6fO~spxzRP1uMh~xk0s!@8&O7?N`PsXDCM~ zW2Hrc2~<7uFrg(;@*jKTL3#osH=8}h9AISZ4rVg*fY$lf(&w2e+&=H zpKU?*(~fnn&#rWL8}~q$&bi9za?Np%b#Hd5Tnk)BT>0)$&s}$OSB;~Ov)Y;LTIwF< zzUc~gzOxNq5)ok zHNigTmzXaXvD7v?Eg3-7|kFdn?&_xeZB1=)=V(1Yj^G?iDD!_m>$Xq3dNv4Plb z{1$!^pO2T~mAD7HfPW-T5Sw`wc9iH!d?eENytkQ1C(aQ;*e+~7dKOV)BEH^n9Zg2B zqUTV6)*@cy2XX@pMq{!2$RuPeD1@mnjE}_UVF3sOpE<~NM?%3gPRGWxX08u>%sWmG z!EG>&J;$BqE^;Qej$O~ia3pNTo#Ig5XS#>G&CP^3>lb^%w$mhhg`LcVjtuzlG1+!rp5&lkhl zJZ29Y#r|=NpL)#BB;Tj$bBYX~L zgZ9Wu-oslTBK*5!!9ws7N|6J|LF5`Toaadn&=hosFTqCs@hq|#m7$SHHMqrlZI^=E zuo4~t2Ji>0K^h|~KpWlz9Er>Z7K8y+AQ0IGV!&iRdNf3qAZdJjILmkMK7li!IWh?O z4|#?}ppTJ!-p!lF`+ZB`Mf3y`i+n_cpd%lpdUGVw7a0aZkj4D^GjL8QfIV41H~H6YLw%4D?5Aa4YX}oy2>{ zhVgFTLp-|UKm?Kn^SM0k3ZHAH@aOuC*#~DLr+LQm7Yqe2d7OXpzT@4z>-jGKjka-{ zfsK2`X_3A_f^Grl*uk6?T477x+KqS) z&oVFBAzUsiI-*WrVbx3n|C)SDh8~q4pa?Jq=U&F540yYutg-l@1(RYv& zcrRosx1UG!7Sa~&34Xy6G!;x^XM-+iW3ZOZqvwJeWIaT=>&zj5p-$uidK>KGMuJqJ zN5tG^H~~SyO>{5V4uj!7#DzxVVmt}C%|7&BWtzf7eoww*FLJ}V7hG#}8ZZGN5`=8y zIzb1rjcA8Y;F6g*ZX@rolrpKv6tq5)1{ZJ(ff(^2@yH84nyli+LLC~#Uxx*d1r=y> zt{E&tT5%fKggB4;;49`NOotUr0$=_7!c}rNxX;K>v?*-IJ?9yQ4t7C~aVywfU<9^~ zYwz1lzk;FIU-$tuh+n~WE}qNfci1DqJ2%)h+%8zjtz`!>W4KoQ_5O+OQ|{6(e~e{uqnM6tZ#arwKtBSpco`wZrtxv34<8BFBkPf?K*8to35XG9u_M7@ z#>jQRDa?Y&u>#&bKZ!@3Bu^2q+0$%yZa$iho&agwGw?6y%Ew}k`@mZLf3wjLg2S+h zALrWhnJ5yiB8u<~v;mR>f?xo1oc#=b!jDWl?mrG^d%+=SZ?GOw%m^ znjr?Z6`kT4?Crqu&Qi37XilW_yYChp!VF+Xvsv_XE)4HXbOGbNv;8Ca=a6lOEP=zA z_S`MN#~i#N{vSf1Q_&jaK3ql*rMn|t5tKa*7Z4W!=R4@@Ei{R%GdxJLjM?E+rXVa!!jhUc&&m=N|l zy^I?Sj&U{I7q%Uz;Cz7Z8}nTdz}^RskOp{n+=1({x5!{VS|tLMD`w9!#c&a}5syOe zaeA-^t`kQ!5e1z{HJ&bd(Taef22VO@!=k{{b*#mT>|BrtT z*MJitc`%&MLd)4L+!K!Gnt_JsbLO{v-ZpQB>W$IC*A`8g?_>g@=kzugddM04&%RwT4Dsnk=uzl_?dw%i@av&5z9u%I=*J zoY^t+{U3cwm!H$V=`)v?8*7cukG|u`I_@~^hUF2#d@uRFbgpcgwkC`U(+59Oo8%8f z7w|j6BJpYQZIM_!M7&e*fI5k_Kt^yA*k#N||084uF$GV@E?~2;So9-04AbyxnzoDV+cpEfU=lc}4rg`^4+Th2r6oa!G6HFNt0JTci=@laqLKs_{$MV5F9>LLK(c z_YQSWas=AOS{9mq8-E)686Aepx-m8NYerP}t$bf5ERM@>o4q^Jl({T7Jg1p(Db`ka%q;dnm2DAi=;iprC)F@%N@Qv`SaDs4x z=pH2_MiUkITVe+}nCee`BxYho;4!cQ5xN5LLILQ=b!1zxDg0hp50haZ@EDngMG$|H z$0@1siEy=OgZQFkl60ALr!-62K-Npzjj_m-f=mGp7Sxxp4mW%p}BE&64lSK=K zCy7<~IG)Km$)w zT&o=Ewuj~?b-N6`bhE14Rrl0|=%?r!R{6^8B}}0+FCb@L?&}5z=3Td(*dW&sAAEUQ(hxysCvoM(Z!;GV={0z-8g}g4|ITP|6Yk{X?%Q1)@B zc1sK8r{uY^vGOH~J<4naB5y4lFMBOJDVrtRA?YO;jupa4KBvCoRxww+o1Me#%dM0p z$~4>%RXw=sadju%mKv;LO7Xp-VI}K}k%H9hTj|$+r~mGnelO$P?^emv-#&SHEM;%q z1ok+d2IAo(uhBCO?;1EH`c%xodXaH`jX!-=1q%)Zycb41X z9qt>=?~`NnSngkB7e7U?fNSB$yv1Ck*sAHJ?V?^QOBW0#YVmhuAHFsmK^(y^5Z{R< zxE=0co-yHUFh_$8ST4W1-RuPRJg*bRaOZhdaUOYzy~K84tO5tk+hwv|`3>gWBGUe{GjxLU1 zR}^0@T4WEh3^xYzJ(|wCuKIy`S=GB@Y2l1~O|CjSGc7XZz?U;0roCJB=JxxRxoa)a z+zBSiJ<}85YlVD~1_tkl>>ZsIJwE1j)WeARK@!;$eynT=av5bg5!86W# z9Lt)a8*4<}6Qq-uP(S;DZUh*?8s$CBDb*ZVqA-E%O1O!~gcol}+{8x__lUdrV5B}f zg;BFPY(CtKT2Kpk$X#Xkv-$iqUVn~Po1h%sgSFsigo;5cp0odjE+pDe7Qr>)Kv9aw zD5@6gBnPFHQkU$CVxfvuw^iPeb{8g-|M9xMDK($`i&%l>^SqT~>-kPOrH(<)Rjw`0 zb&eg@O{Vp=4|I__gDy+Iucl*Ja^Zr4guF31;><~@L%!)h7QYkz_wvn}l(W^S?;YoK zUvV|{c42P|Txuq4b5v;b!|1nBSj4o@kE(EygD{E51vs_kDhqW1?q>*Ci54LT;J=_F zu~&FQyiv4@4CL!o9{?r@ms9Gls&ldh!WLvEp(BP7IQ}>O0gor{6EATWVrJu+Z%i&b z8!kr%@cA_gw&#l2XY3>PC7Z}A+BwL3Gzp!9wB_~S6!;Hlk4-03RE*$1!4;uSxJPtA zJXaDdZ6x!`Gn6)!Q#nF@knccmqAZl3ilnBK?{E|oAaU?9{m@N03Fj?WD_4?}vcE99 z>QeN>bmw)~^^y9R%EV%IVb}by+?*`SpR6D1&(Gh7zU%mA_$RhNV86(%^k+Led*c01 zvAy!Zkk(OGqMOAmjrkUt7B1jdNPB9L;HjE#r)W1y-=N8C8k>l%!zUuGfCZl^?jc_; zKPqlV*m!M`D;TBxtlbsZNOMQpR=`mP!FMWv_=ImE?^3CPD(VMzoIUUR&sR!YxnIaj z^dNY`_GM$)3VO4Dlh5RnG0)+5bQ3b3-R>9qr}=3*6zK45L4xRtxP$DJe3N2>@~7%p z!1$0Ik?t5_OmX{EX3bu3?bJ-|;y27u$pLUb4U z7TZT|6aFo}CY~q$CLS(5s93HRYNAys@&dV2IbQQ6pf2EwhE|2E^E4d;EUIF;OZrk$ zBQ6uCiu7b5GK3q<1p51U+Bmmb=NU&D=IL5g? z*8Bl^x3kY?kIx-h_@(@`F43@9A70nQddD%%9qhCFC(;twhw32xA#=)pD|)LR1w0RV z6p<8B8JZZ@KWanlz&K}IN$km}yol>jt7B$G?F-WecM3eNRcp5e;Hnf!knoY9iwFvB zR55-4$$$sJ|7nVT97dyjy)uY7$;_f#dxyCsuHo+Xo-OXXyicLC!|qgizIqn9Kl7Ew zULL>iDqo`)vTeCbU@ZQasur9SNO@<#4QXe^NYya4MU|_vspkj8Xqf~Kb7Z>*`CBtH`TqWQQ78Fo1*$Al zRj4Ove};M^c1Mg0pB1T%T~Kdw+{rj=?8<0u^yJvG*samVh?`-?kh8({gD(b3)$L@L zd8Qd7ek@!_1>=#tvVR2wK_hMqz24{aF7>VEyN}TGjgN-8&Q|XF?w8Ile7?xwT`-s2 zgr}!V?`Y&2<+<#OrmN{KOntU79EggDC**0WOfX#3SMp1CN%2Yh}TRk?~ZS##+ralFt=wBaiuCpZbc$1}qjYTIS5Z~WIFsQFrc zvt&e3-~4ykH#0u|QKV+3$bN@re90W05s|j!&-_2qjI!LE;!fqQE3Q`k)LZK=SVlWT zy^;P4Oe%Uyuu672=ZzdsO!m(^1OSf_>S-b6;I4Vukf?rtw9qQ&Q7N<_&54j`1L-s_l&2f z`<07u&v9RJ{q0O~d~^KeY|B@#kGj@6W1O2^-90b7*L;io{pm%_32qHigH0nYki7&( zVY)a(Mk)F#bxMI63z(?gpk1n6%-=t2=LAj+3Jr?Zw$waRmGI~^mF^J>gk?k%3`dr7 zmHvM`y`8|e#4Iq5Fr-xDvsH#5ZT_E?e}-oC z$ZK3OvAk17c9qx=X)Lpxb`JD5_E$1Xums_Gaf~!so}=olc^g<2);GcwHa+Y~WKB%d zSaa;kdQ|MosOl(9?9P~pk+oqPLzN-jgU$ttwXc*%r9N?pBurc-*h-qP4aj`(jIRW* z;pQ=`=`Hjj}?}c@2y^3^GW~A_@CveW1?5a4B^$tE+SO?O}ap?Q<~Jn zG-TlQ(DUKH!&-%{ikKOd7WFtfExJ!sa(KJ&MG@|BJgjkuA?UwAsWvF!n_8f(kv!bIVc7};BSGvyXlQ+0dw zO?A5FRlxgz7XhSJtX&&Wt{JM4s~0JED1c&*EJ<=z*q4$LD^U&(Vl#X(?*G@^S-(Y< zzJL65%rMN*Eg+$&7#J&vfxWu6uAOVUcCU@yU2AuOh26c1iV7&w-3-%n`h4%tfAL)| z_S%adRy^~Z`?=%&e%)^@>GfP~Mpb_KfYQpsW4X%Dr1XEj_DWm+{ppXKpD!}g(=Vlm zWNiBRIB!l#W!c+uuIg@Grm3C%B7a*tBYUH#Xit|Y*K++{ch>WQXP~b+zz`H0cqFh} z@b4k(LgGS4gk}YA2wE5<1YHSC_7C;z<~!ZHx93EU47VowE-qIzc`VJ8kqwDcSYNa; z@z z=ww@vzfdc>9`nJswG{QS-GTr({U}o~*v<#i?1ZpFPce zc=2Ap6iv$NJIGz#v&o-6WDUqE&0d{n$-iFOp>Db3sL+nztz-}v>E`SOO@PZCcC&Vf z`w7nu9-TbWeJ=X_?z`C^4>;yK)8|t_e8|PXRlf6mu6j52KI0YbExG;elBRWNpJ*?! z!>=ergf&P}ViZi-VxaH!3ubLe!WVIzyc1>(6fzL*Y#Z)? z$?PF=1(izoVy-iVOe)iqnN7!l7UwxAWM_~&$xY-gP|CI;zmRLG<}}6#%x(5FI}y4L z$(pMgtLB3Cg?78PrS>lSgm#cqiH_JNpk%}=iIOVJ;syI&)2*6$6-e! z27!=aQ1ctnN8(-XxjoA4G<`77w~lkP5vt|Ea$~89SjgYzSA$DFTG1jZHVd!Eijkpe zit-uy-{nXy9!;&LYv~#EZ2B<$5mfUN>2x}R31tG9o^)3VAtRt`vy&J@4x^&z%}f$I zO!K#1&O#GPZnd z$=d=`?$BS;GRAxv`KI>KzjtF(R@}DVIC5*x!@r;H`4Cz?fbj@F-q6>-I)L%q8Ke)J z7;Xqp^`7Ya%Htaopsu#E<|I?GBZas@@1c7$dqHpelZ}V@<$jm#o^^p$A?y7UJl5#i zlXkRRorLD0fyhXhiG4-dOE!orL+p#}u{;54X$sd8HRx?69VSgXq~Db-=yKu$oP&Y* zPxYYuQ%+JpqnGgpP>;`LqqMuUziXkEr}gv#dH}PDk>~?J?Jy8$@gPD+yu^Rtqlp2a z8*e~&qSsK<$Ug}eyZ|c%(nbr^jvm6+K&Q4IW)yd^fy7W^3H}s~L`0bpjyv3~+4Zi* zp>UsfDH)mfPqzG{;(O?)N$>i<-1pFWCpGE8)ho$UQX-yzd^h^rcE?h`7QgA*w{J)U zEp)edjtL0%lf0g>Mz(`y2DZeWQl+U}RO4y;hGx?D=w6ExhoGrINCnBSzJ>bxJ%AMu~ITh5$%c%--IB^L{f=TLo`4h}W zm;G<1r972piEns+Ay~Si96=~-G;x|lDGhy_{!HJeVYlDY1;$ zLAa3PA@0;rm9&jsPB)|nQ>~$v|C8toy+Vw5Lo6dj@-@|!-by8tPlzC*2zou$O199| zk!0y^`da5%lU6yp{8Mps!P}g5S#2|VeA9h-`)=CH+NYI|!tQ0=TlGBoKmEt9KVtEU z#?kR>;zFA(2y5kK@WB0d`1a6WrL3e$-S2#7R%=$31(yGE61ooFWnS&Q8+zV$`wWV| z#y$^ye>P|vc02Hz$5hwbbdbE!v6-7A8RZ*lBKktf5td6KF!^YLbU`=Zvk8HGL=7aZ z=n-X)94`-6T+nA&YrFs%tMq_5@h17HT&JWVuTdK|k?2K+f@3y}ZLVDodZ9aPB6Emd zM!h5rq={%x&Larl1<%irkX^C5K9m77ImE(aXH`nVUa9dB5p7^H6(#+P%OB zl}`@7oA~wo_fq3(Uq{Qxb}hoDHdx>_S-Zf^*E`gwm3}6bhs<;Yn7bKGprVemOrgej z{_u+ns101;z29(I-^0Vzj|n&t{H%e=r^u}VDiTbZVaDhKQ#T&;n#WRm=)UeYmXp0XQxi5(=O$y;O%xrX{o z|I4&yW7sFm0OmV=j`pH`spVu4s12?YuLu&RE6<1@#7$xr5l12m)}saNDS@&aikHPn1+Aw=(n z^hc_g`iE}BM6jjod!~RY#G{ZyQYmkC4tLD6*V}@u-ln9wpjzMRWaxW(lfjq-6(cE?k}FV zzp&=n3i+L=7kz{tNcANb5eW83?GE$&jmRKu2XUMf;7zKRLV%1jRO~HR%P<{Ncx93r zsvd!k)+{vxYWHZEE1*;*xrB0|cfnUvnxY3#KgnFuOtzqG&?`&>-%EFDD|M5)MUA2c zQ`4w)Y6*RseoW7z{po@9H<|}ua0fC8UyV*xc8cxzM8`WTZ|-8AWePU+GuN5s8Xwf4 z)qI7$bat^LZ}iVsUn5gjzWV+k_s;VhO|Cb;k?`>F`;zokj_XY({gFFpUc%tE;~U;( ze3TOP16s+Sv^;{*@o;^hGLe})2S>tA;YNNRC}rqWIP?n z-^p`iG3iU4rIO(}{iGVwz32^e9J2wU%~9yUx1G!w?%H33zd%M8VVh2!&1WxY+`mD=Tn>HecTh8vN|)|ANCJ3sF#Px6`4t#&Zd zyR>8LX8qk~LczWYpU!VHj;+rzbucftDORIpyE&9!Lv}MH22G3dXrc-0XYl1*RHBvRy(b_e|cqbMxKAx@82hWc=po!$-j3G-O9YFeYpSioUf|!P4x4USzj3H|kiTgA*Ycl`hTk%r44vI%Y1H9{ zuL6u-XY`YGqqMc;3#<(>j`_+~(v5IN)Y=|ce>msCZ9bbA0XN1BW;4xDAMs3N7pQ4| zsD9{Mq#fvmW#~mr2ZhHB(B~{ijG%Sd4q6lfS)-hlcPX2Z*_ao3jE;aARWSGfWQgRK z;HG{?{0-{QT~sjjjBH1KAOgwLKnJ-)#elE=3w)Q;1L$*9Bd9Aj(6NyJgc9$O-+^kC z#nn3o+Lze&S|3}7*^bz%t@Y-v=2K9Cwy&%%*-`jBC*enJTA%+$zlwiM-MxR4yM68P z?YC~lW8HE)4;tFN-;Zwbtxx$K#CL(tJKyrLCdoM2G~eRxz@70{e`6o}AmpZ|f$y8} zwvBr<>=hL0pYMsd7aMlE_>w3_QY!o=a|uD-MSJd z(H&|A=$F2zc}idTuH+_9miqzi?zK8vm6eNX3epNIhv`!k`V6!_eXtTxQbxml?gYJW zJ{3frg3JaXlL!G+>^O*>xc|-^D9%&-`LoV2s9!zhiztbn^Vf1QR0F}Q7IR<=? zAC-?%oZ#o2ZF_GHsSh{C8qFZWt*fDz`#iTm-CtBMkmvdFZ%}DY0KXF_}Wj<6WvzYsAyvTvfP5~r`ZWP+MG_m&iLOk7VRoCY2*EU-2m5w)ZaON`( zhuT*&-t&9FoM6|ml<+$tWqx*#wtB6W&{|wYcg{=k5q!12M(9s|a{HlqO!DY1^}Cvh zb*I`f%h?!>p1nlPCR(Gb)dGsXOPOL<>2;XfhO&9Ct)cvT(Y#H1m z2}Qo50a#<~3z~|G=qBtM=p#oEzY_xffvBW*>9%?W23`zF31)-RywB?!X*k@ewwITQ zZzXpWqx-t-bRDgGr4fn8N+N&A`l$YK&8CV2Wq+1+sQg;9&G^E+(&}kFXYNs7UGu!G zHb4DW+|RLD`M)majw={YG_nLfnvympbBmtj=j9~ip39q*w;?C==bG>Tea-supzI8f zxkX3jw7%XxIreCW6|otu-J9eGUeWbaLxh2H20qW_xcel}d7eIAx!%{khkL9s;I1sx zKto&u-3z?Re5}52eBFFfJvZtnG6V4~>Jd2uG&cn36NO>`X zwb6zwk4N5fean2i`FMCV)r*=rR5jKf@l%f=Mtm}z#Rh85LqBOG7NIobXWP1)hSdD1 z7+b!!VnuaM?X~)zmNbjgJkXR{_qnp5Xk2b)R(Y0Nc1_NQ{F8-0fJgG7_|K9Mn1Juk z{hl*F?{MCP+*4Vv)9-!d({~oOvZk{uLN2wW+DF8?c9<4rT7Oy77w8L zY&*9{9(O%HdGz+0<2}T4h+A*HuS=n(o9?t>i{~%zMLwavem-5iZn`CDZWCchygUSM zr5oxbWGiUZ4q=Un4pd7zh8jb7gHn@&CznKIV&SS*n#G3#k0je}w~ulha;_7)$;Xf~ zs4}AQfuNcyMZcg`SPO6*#?Tj-SL`{>3vEwVgIj0!Jhy{}aRy0W=9=M>!6I~jyaRaE z9wC$Q6tW4un@*so08MkVe8f53{GcYTvSY>Y%30MRbsbInESa_v`+Vpw2N*}ywyiEM ze_m2uTv2Q)Zd0xEzHF0!%as>>1AXv1B7ypCa) z;0=`se!abeZLdw^@O3_Nv~+|!vK$%CFs>K(f}6!J5n4$3$_T8ScuUSFml8SnQ2Y;U z5&98msAE9My%Q$S9GOg)vFlutT{UiZ+~VCWZm8k2?k~+-Y90PoA%)WpFZ&a4Y`&CQ zqGO2?ay8im4@ZNQE&Ms#=z3dCr|Krvy4uOc>t=8JC+O#L_93?0=AU&w)rI97OIwso zD(M8X^yQVUYUi4MTAo`y?2GNg?foq4>pE49E43FU=KspA$ZeJvpTDf=eEAhyHtW)0 zX^Ts-n>vr^yy>@1Eyp+V@z?8mD~hRK)vGE`Td~rVu68T)D-7xz+NEk?(0Uok*oY#neDL z&nI!Ooqmo)TaEROZMtI{Xw6KbD6NzyC|A`R=p3lekK=VqF(Y~vX{IJf zncN$jr}?6>Mcs|M@cPc?09y;k3x~HO*>>Nuq26Bev9fFVrc!BHl9~gZs zZLA}0VfNm3hjmkZr<$YXe-_^;Sd{lJHz;p;UV6cul2^60YMrNREsgO z_QGqM&t9JhFUoL)J&i4w_Xx#Y0JqwC+1XTRqy`bUL7DN4qR6-Cab=P8MJV8gI>y`d zwng><+*V^ZSR(vV> zJNv?=r@`I*vD<3HN}a2=oSsX}MmsCb#cb}j)8c&1*NIKl6KFX$2dd!l;EDMIiIAOq zvh%9_o9z(HQG%?Td4Rdf^wL~paknkB-*jAbPIq>8Jh7dzOaUh0mMU}Ek<#^Lmn)*H zx!P#cEemS*bG)@HmY;Pm%fA--=3V;L^`|AHGSfS|rtFABc~5BO9Y3YV*xvpJv;Ap}Xj;-!p} zCdFtqkFa%gOm+l0Ds9Ki?sfSU0VPD?h=P{+eex3WVhh`qUA9JPt_L4$)wGk)`(dxY zyFTpl?ziSmcKP+8wwV9QKlbZO!5<|Zt5U3^l&;zXzQqx(Tds(?+TugxRsa2Nv$Rf{ zCQgEPEmgcAo|h9)g)CzBL*_Y?`b_qvvOz6nL<`lGpr8Lk?x~fUTvE8JoqnXGa>W{h#BXQOnH&qSMCnv;8WriiI*pVn_@AN0wn3< z&;dFiW5By!p!Ab236cB|=PUaqaJGzutUtnZ-}u$I-IQuhGxvtCKg_dDSw^Q(V_I3i z#CWB)q-J^Tfx1ieufd6Rr`~3)tD9W&xbi|pP+5=ScZGix?FT=&wjxic(>)E2YCbFe zUH7(K&0Rebmj5O+8x-7DSL57J^|PW$MW2e{_075cs-E^X^a*?%cB*k=lZj!^{hxYR zT-Ry;A+3nJx?ViPjpb6sDs&tf$auo+nPYacv1}*Wm*|3JtGpN?P(GV6EC3Cnp)xaBYNAQM38jF0LT8V`dH ztEcgET`IT<+g2Z__NnozU08R%uBUOF(W|a^ZDMs%WwVO+rA;`Kz&;SUW{brywVdml18K! zosC^XHE2I%xeD|Gl9E)N!E+8 zVmxT=ud1h^A0LBlg*m(;UzN0QQdjf+xvpGG@ZfRWAfZO|l^cOiYA~__CKBUd9&rq7 zgx|n0Y#LD8Wt7HS5%0-W(21>J_AnoqzU&L;52iJ}luUq}G!k2gzJt|#S|m+5qG(kQ zYuhIkYu+WpA!|meAxHDXx^Rpwto@y<&yoP?E)f{5B z)W0%1>&oly8xIpocX)NO==SKyo$*nVinBtPJqT^ zCXxkOCPXY2apf{}uE%1d@CjH1(m)vr=VgGnM9AgbxNF=-{vJOGR3_zeC-nmm`ClMc z(J??w$U;w{L%_T8NKI6iBHOUe#20V}m(wBaa<;uDlRX5p?^N1IcEPV^fYT9jHW|?WeZ#ru#GX+@mmX~IO<&!zo;%^ylUTM~uwiuVz zWmI3U8c}H~|EGLm+23Wo%f?q$Sv6!+A5-J<_VL}rdVlP(G$Ag|(PB$@Bkw>;aQM`Y zf=_|2d}`_}B%r&gK3cQBg=f5v(>KUxoBLMXNrnSY;0JOt>!ux|NnoRxQUX);<&(1$uES&w`r&As;TblLku_qMLMF zN|3uNgTNbiN-c*z9xcC=WO=PxgtW#AusXaqI4w!qL?34dYmP#9{66%PpV2?4?sO8& zdy0uK;J}GM*CL&ej%tYVT-qn*3I~NL;ytOgVpj5%yGjGaD9@IkOQWThA|Wi|8aZ8^ zCP%hopW}(WDYz?JK(Euo%33Cv_t&4OORIfXYXFBUZ3;Daw1imuTc=tDi;Hc5{hEEb zqaipg&qIZ7t{qtAS+TY>s^n*}T(q~utDLA*>)$9>+(t$?+r)Q^=v(wV(qnALvoTW} zZ3-xGRnXz~5@W~Op*4-n(V_?WOgqW-m0_cstHDd}u1nKoGXp^*-x~|ZchIpegY~oB zYTVu#e00y~@%ULF^S>4iLK@eQAI|6UtHcws0ey#$BnA;UQHZ&tlsZ|imZE?~?%;#? z>HHueOzbIT%YLvYVlKE=FT&GRR0MK>YPh|^APO|a*5GqsPVPx1(2+ncp9|mPnF)+5 zJ(F5W-Xum7Zulf@2lx^@VJpxqghL*H|D~7uLiq=rdX40G$xpJ1rDBMfF7yzaiEiR5 zVUI8a{5|m^Dn^T|!~)2yPI8>H)^XH6(YDe$-`dWaXxVOgZegs)tmmy=Z7H@bHpufW z#pViAyeZP8)E_h_SWB(Jc7uJS)owXeKcjA3ZBX^a+Vq-vwQK5En;uwp+kaq%9{+^} zw0hpr-0O8h;|?!k`iJ)kIBnR$Ohp!e0%@WBg!#DRnR<#m#|CKgT;^$_VSXEkPs4|i z!9ZvGSM%Maoxx%lYdC25rPu5BGiR^?%6>6{FXKM(-r_)*=?zey!sd=wh$}i#9i;4( zXF{C#$k+3ELIcSMHeMW+eU!U$vh-6tDR!6kf&0BedMO_QPv|vx(x<`Yw+!72dW??v zZJ3*`g%15I`V>8bx9XtX*1fI=5&{&8cE6}y5FSZlwi2a97K^55Xk*t~(8eEY( zrDS-vkAxe-W8sic!J|Sge~tglHxSkfPlPgIqmT>H;UIU)nFM5$yEe0xx7@O%!1oTz zM@zb8j&+ljw7vnA(LpO`DKNLS^fX180!*8XElm4NOD)N^$F}ZHlXJJTvGcIKoBe|I zo_T`#Sp9UOwrHM`+A!fu_H9HT{5Sj=#f>6AhVhF24Hx29x^-_b+->_fC__G$V6SK^+0^-0{*( zX`hTK3)Q<2Ar2~Yv=qCTCG>FWDsdDage9N`^bJCS%cKu_ z4~@kr48<;?!=W3#8>vx?KpD|Txh$`T)2tEmg_A-J9|-^cAv@qRJwq;fw`e4Av>Cl+)yX0dz5Hpi;T-pr3eX;4uSLfgLq$Jlz4Rn>~fia zPC`bg*W>}xV^FOf5dV<6z_hy>B6ybiFYKA=1I}JQ$sm3fNb#F^Uw*HS26aOob)MP7 z`e`?6ZfVA|2Kphz5Wm5mjFnLNy5nE5OW0p`W;8c_G~u8;Fa=9PxoP58TebDQ-%c3=$jg9p02D z%0p$NbXBrQW8`JZ19deTg|{XVAm0|S8PEm2#oh(qeKYbAz7w+Lm)H+%5_SmFfa}o} ze9Ik?C+ZpXnc|d3%Ht#pbn&M{Tn-Sg!o4^O)Za0}RiRXf5IcxRgx`fnu<>R9ch7my zxytG8{NT9cSnTNS=2G5}&8XVTHUHGDHPx6|hd*~-%3)9VSR=#R+B@Cvq3e>`=3>+{ z|0sPteG+?sO~7-hzt~m4DjrQ7#gf!$WsTYls?>2vA8a7`gBj%-=D~ZN^Znxc)9aDp zPi+H6NB+X1aX(@r*^L~AtLR2ml6H$bKoOA1-R0Kv*ZK2;oBUEq2gf(~u92?FOlgOh zEwmIdsX*E(R{%3WtHgn;-!2*CP&q+P2lw!3UYl~<5u^o z?o|C6GiKduyJnBY4(Oi*FKV?Vu62(m3AL>YqMG?`&=|-;$Oe2r{ZzZot&3|4Q$vnG zYsExoOCEi`DZ5ZLU(WANB8ka0)1a*P*AyyK@=$T9+)03KxKUQN! zAAXT@mSeK>Dz^mgB)u?SyeiIwjVRxwao|lE4n&u!vOjorf{+7{oefauD4(Q9LZT2L zeuhmrbCrYYE;y%EaNe9@h5A8;z%)Of(P>&}EKCA<1IZRg@UC2uqbsL~%hds}Ijk{M7AK_< zqMg?Z{ly>R2Jpb};1jx{eoMXdzx4=Gw>2iV8 zO8y;`hyNpFOcxzOFjT2i#W7N%d>`CN1=3BRz*Y&J1(83`|Ha?rB*%Bq_Rg_oLCk(* zALuNFF8&};|88;qR3MrEyh;umyCX;Bci!y}!HLgUn#c#Zb6 zJMX>Clhk!17s^@CRawW)Rt&^G)~>zaVgt9vTg@roj6-Ap{| zgr3+-oI%b?8{u>%3f@vKIF9$hW+@Fs`nMt?wBmEQ-Ovxsl=j00p|;3;WVHIPyj+?s z)(XAFSm~mis?@6U!J(W3arufe6mpKcsveERrxWMN5XzH0MSR3^&_!@#JJ1BIJ?0Lc z;m(*l_6T*ye#Z`Ae}eMz3vvnA6?2q}KoyAtPKr)#tu&Bth~rla?G<)k=TYu} z&`jzkT^0Z3?T#z9wHAZ9pV`;C#s1dWkKYDPh-&9Fdx>?g<(uV}ZJi_6xfZg|t#*^; zPm{y6%=rnK<=Un}Qj-mB4z!DF=@U87r-SAY?t&c0&uOQ6r21w0-SrI9x#6uu59cSx zJK-%7M-K%TmW#^}jZDWo=^V-CCeW2D6U0Mf=lO~_({Aj z;mRxEi}XY6$|LE$unOXSA|D|BCXZ34gWo3{`WExSCmkbJ3q3`fctZlMp1c-Z;W9k8 z(NGPgsiVL#*bN(uw;^YtUuDkYR84*Pc!>3}iQ2|*1JNtIP z#<(ZS7{y=lQ&h-ObLA~EE5}Kjz@6DvxXqu2{$Q+7EnF4=eH7ow=jVGoXXF@|S>eGfvqhe-^X( z-oQ>gWAEtrgL?}#b+vR~7b|{RjT6};{Q8zW{!K8u*#AjUh! z@Je%%U7;;-_3;?!HO;fVn_c^W8Ux*-C-^R^srC-&cZ+na_C52FJVzWNszJLnj83Ch z(6cFT=(|n=-N|0Uj8|bx(Qil|kUT)wjb@-MIM|K?wXa5q78E{9xC9z`2IBE2DNvHd zcj93&QJN*~lHN$b5QB^|9(FOd2EE5dVC~FOMkxQNSCCS)11Np^f<9~+oc-hYcK9s9 zu{UQTo=Xj^i zxdo#6Wry8y)tTxH=1=nbc?`ID4rf27uVb6zuA?QlSBR4?$V-5Jvs-pZ!=XYOA&wEl zms!`7&A2&w1rFPL(C$!7n{Tk1xjNG zk%2YAwgO}1D*6z(IbmoC#P%QRG1$8q1SFoT%1GrDD6sB9PX_K@sU>j6rb%ZZ1I!W? zpi%r1bH(T41URiaDL|Sa)`(tGUuh;#k|d~QrvjUCJo*HbB&)Cy*j3CEug0d~9`MP3 z#(c3z>6hRf& zNZX*xks$^HuQHL3;^*`4g&ks+bW46L4^ar^7-%<>Wi!lCR>>peK&hAbN%+7U`BmUN zZ7NKGJ8-zTSK27QR>BY*y^qZV=X!hgoc5rul|DiLud9#lsOCFc$;@R{4eElq?siRq zO$JZ2@7WjhJ*o+Hn#!e5vyIXgC zBkFtDWmP3Vf!(D#1vXbI-QlJ2#C3LUfFgKLHQT4QiIYVghu~ zrio+4KcH_`DBKbjf~zG!NDwYT?A#2$orfgCX_+N96sr$c@cp-ZArFRahVJQE!I zJs_@c$2_rPpeDP8i~@#~4(`_p$Pr{avJcq;TWE2mzZ@r>>UqOoub? zEmZU6yc39#t>O80g|ilk2gzgujVK~A%v~E9gw5&x9EltK$AJAo`iU?4fs+= zR2)8qYUDI}68y$yn8(gXE+TzV8lFQc_8e}#pXg9@5NZZWt_S`P{u@sG-BJl&b2eBJGQy4hq+Y%db0(Zej;l8kGxD#w8ZA)JP{?k0-8PLaO z6YWS3DiIixUQ`0PgCGb!(FG`cDR2`{Awmcb;wruc4~1%z#nZrLXM|3DSKJDUw-n&G zvB+Tfo&HoT@;Rt^Tgf`8_HRoU;LX=ajl=}u9>0M9#&;L)3aao;*e+;<1$3zyo4e?RG25chaT7^c($(4g>(Z?cDh(6Z2?C+4|LVTlCPWt(a2Ywrgl(oDIv;H z$U@k*rWuS}EztBtYli}EMY#Pj5H$&ID z4gB;8?0J5J&IF3q7hvL@h8@(dXbk8PY9I&y6Nr49pz7ZSb-x5WryeS)et;g}2dKuc zLFPsPsUcmq1Kk5t%H>0##q|RncR0`kQ{nZ#tl%xLi5x?gcu z^?9mn*>b6*o_@RgfgaeSYuDKuA!t~KpdSs|BJx?R}q*ve&P7V z3;$n!%P_?A2y}>Fzzt$IGdvy5&`c87jE{idVZ+3FS&P>>WGZZnPpj% zvIl0b%YKlZldZ^>WnIktmC-7rM@D4Eko0S**OT`p9*CbG^Dgpz*uLP-x=reB$~yTE z*-L3F$ud!}@HB=aVX%yU%k-g!kb{Z0cuzbMSK#4zcljYC%1Ucx zZsqOD|0=sx2U$9LmIO+vkU+yg0)2^1KzfN)@_d<6zCqJ5yledKl$GgW>4Vbj83_$U zjRcJ*HrSN4K0P7*Qs%wvJz04Av9y_~%ToHKXp{5eizDZU#s{;y3Qd@Lw_>UEjJUJ- zhiH!QD)t&_2i50Vvr6V+paGHVAL8%qr~EJQMfh=lAAf;=J&5ET{080*Z-J9ILROPI z1F_UHDvQ3%gmE-ChcD$9LeHR3_$?fQBqQUIcSr(=<1P@vZ|F~yMWZnUdx!2uXQ0hc z3$g)`AP3=W_!30(ZTU6aH#Us@o4H9}p*jXg0wQ8?wf~eC^K5eub#-%gcVydL)^nDw zW`_|qHm>beGru~gs(aP*${UpzDjCDyAby=I#Z~7kvC3D5JB9(3Z>t>DNi_qi+f})% zUs^Z#meb9cp42!BVif#a?2mMd;;1ZCHc%5Bel>1-^3Bww)CVcUGjt8fMqL`MY~ap3 zlIBmFne`xhU}kaJwbX$rvy+2U-X@<{%i4ZptpAfYXss#eH zJ9L=q#7$<8Q2E4V+~uF(|Lxy|hvL2c@BC4Og%FYPWC(eOV2QSYrc_6&9`%m0(}P$$ zCxcQUKi>sPhW+qFWDn9Bc?jQvTO(f)4sjq)kYmUWWEZj>nS!)JAmj&p5}pZnfRo?| zxCj~zJ>bLn3tT#PinTBdT|)_}C4mw$j?@#k{Udxmy?Z^g>pHkj*zZ^$TXdF&X2i6! zc2Bju>TKns%FUJQ48`T6%G#ER%TJcCDZf}|FI`<)QTnaiY4}<>z4Dl$rQuHHWz+t; z4S}OnG`W#{Nsr?jU}q%DMoEMq$G~O^!4!Yxp|5Mdtd< zU)fjc&(8XmJ|=Bb>YCJ$wBD)diO!e}k(uGALMH1m%|=CAX{mUR_>c$_w!)eq?IDVr z&bb*i^_jSfL-<2~1U?jhe?xY@0sons z%Za&xY-;ymCk7OG67oa%Gb7qH8r-MXe^INj-g< zi$^buJIVi*k&^bx1tHgC4kq?Ud7sic^>g}#28m5_8&7DoyZ)8TxXkSAH}#{kn`i7y zyPCQv6-}d3^OE+(U61Ma6{#Y$}VB+!bTu1;YQZazq0!=^ns*_GIf zEAe1_1vssf{C)jP@a4ow;v1nQGs&T3TA&kkm0ArhnAS39Sqs;hPv%GQLg**74W?lW zyciw{zknl=;mCSq5u!t?;8bJ*G84%Jaoqy9hWo=q;W{V_n#CKqXh62O5gwa z_9v}$Q0bb|sioITmzRAm&oW#wB-XsJ&&BOjqrf{tOYLRP!V=LsS&&>O9WH;VUle6Y zSerZ|NVMqSc~WR7x=gOXZWqYJH9^tczhOq z0rZZ(#C{@$R0UoHBB>QrIPIZ%M$A3rg80pR8f1X>!A+4zh#Z}S)}Yg{T5O!4N-#ut zU)VyFE6NnF7QYc2#Y#y#$skE{iCH{DTr6rWIxZ|1e8rZbZnzKhoQr1X(We3%h$j9D z&vEw@r`mqh0-46tu$A75)biV<>;H5qaTe_@99S^#cWM5ud|Q5>-=)8o7laqyFC1Q! zUA(B|cB#@}t1dK6uuXC{s&jdxi8%TQufS%CU&vLOr9rR4ZbkKtn^Lbsa%LKzVa}e^ zaBZWiMn4*jYxJXGXv205^0R9)FQ%uaPDq-OFg7+kYGYVk&?)V|Du;ZCbeCuewiv$1 zb!MhhKgs_4){BU?ac16@e+E-Rz7A=dE4U*lGiRJO~ z5?No_KIv}>CNYVw2sMJsXfNbEJO%CqC&G=Pa9+z|^xVKiay8K$KkX~?Ue7KH~e01AM=OW z64*{oAwK$ld4JSZy52gT+CE#(npW2`)zwuas`^)50#&_b1yefp&&}ekg>4IF=V$%e zl(#AG-~9Z1&u@1@vw}HAbtQ`OoSKgA@z4Pk7JW5&SaxWWy$wUNBa+pzdm^6clk`1; zDue2D(TWSAW5R0T3Q;q8du>6mFYIYpp9o9%wcr<8w=zgMS-DejUGZEYSHw&I6Y2yn zFa}+MzUW^nq*1KBGs||IlBlL*#oO;c8(EF}32O8#E#h=F?(X4L|oEzlpMtj*cIU*sX>9N zJj(Xc3xXps%i5TWTr;$fxTAEl^o=MV{Qw>3u5l=I20nsZM(bgIFmV>b-JloT7P6jdYZVeICQrA=3tY@xWP2d ze8AGxy3Kmny554D&eR^S+HM$I9#&>3O(~OA6c}byJ+6u{)nqCT!A^izY?!Sax>(zESx>9zSCou?M^9&6d@E!$_D zMZsjO4D|n{a1p#6sX;8rWe^iByc1f?e_?wvHYz{RJn)=sNwz0O<8OSMJ+tcOyW4;X zV37T*b*#l~3NZ$1zE(A_+;4DH9IN=NVvJ#o;Z&u+vSaz0GDpd@;{4*TC56?OT#NaK z%Fj_jsa5In1~;I}IPe41)DSg*ZfdT(M1iHuy*AuCR-twZV6S zApImwlCnVhUR*AECK@9y6laPngi0X{I`L`YRe=NJP%DC>LFis25{ZX%Asdte_2+aR_&{k3w@_OW9vG) z{mwlOx&5Mbs0B55Hm21Iss~m6XQ-*zRMD)Wk)f+$VWqHYZ29`KkUwLK%Zm4x462s8 z?r|~722t`khQ8DQ8ILi>kSXZo(Wb92ZU!p_nCaEITFD$T;Z`*<9I7*)v(Cq@Ktm2*p@r9_ZyH+n#w% zouyN_U+@GltE3AP1UT9Oe#CWP9+Kzq$G%+eHs5pK3;$d^n7B+%WX2#-;w`E!LH9zA zhHeVFt+}XVrGv!DLMs}9T!P=jkCFA*Y#}3hC0Zg%7sA*SVx{z`sF&ad@&<~6 z+VVg62&fJ^gdBy_;gft<)JJ); z-mg`w8z`oT_h5-|CHt63Vh?bm;M-VNkwrXIEEIJSwi4{bNF*CR%iEb0x+V34yhYsc zpZ2tO%bXRqahA)bYeqxuK4TkmeQT0!xwV=3NDaVZ<+hR;Mdu1K3XT>DOR(bdf{q1^ z|K!$QB&KR+XUB9s*{gonH7#ROi?q|2fW5yd#SGaiiOr%dT4&g}@L@qx^%dzQ@fXQm zc{@;Nr|X*qozSOgLgj5lbI?$Lg%)CyC8^2>>am(L>P^apvJz1%%mj_$)A{*elFfmn z02w92r=SJgCT2W!mGJo=`C9r;_>TGS<2%44M0r)cSNmGmSCgy6 zWb=hObR(b6nwcE-JCC8Lu%)<4d{lH%_*hVknNctN4>Xo5rr%OW0^Lc3=;B*d*V~oo z_->tVZej{IdTaZc`dGqkgKV_LZk$p5&ak7bdr4Z+h=OT_ijsCE?TRvg-~R3XbJU!| z?Tz@_a!0R^y?%5)-E40HDOLEbrbe}R?MeH5Hcg%oygp(<=osBSMYOn)@GQ7%FBKOw zC-v`x+XcVYIAq6!Uy-h0GC42UARVW)s;_7}X{GA=az>bqoZ?7U&ew;g!Ctr_vI@Qq zbG7R4T;+$reFV zWC(9(+i}bJHE>_-jj*d&E-n^668werMSsErpmaWj-A5a#FM-=+5nk(URrkU<&i>X? zZ7MQ`8{ZkHnx|Wr+ls9>%&E1JRTC=8|8y#DTezseShT5RPw|6-hxx%pno6Q>w`_X) z+Ae6H=pKFBw0 z9U)OcYgD@>r?D^aO}HA35g(T?QiW;{>E>&Tu@0P6KYC>+n76wdf|eYA5ot|UF!Ox%X}ZUE7VK0UtJhBCwfQZ+2BE{v*Nz!0Db|R z$A-c_;VQ*pZAblh?M6kM=m=cH_F)<_Jy;Vz5$z|;6AcrM!zy?OWyh!bI(g4{75-_& zOX>x88L1ICMSqJIi|yi%lJ(ME(gxBDiBEJ{xI!=o@Ut}ZjDO7Ehjd7H)Plxid(bUN zKlmK~i9OBCV?xbH8v7wH~P1Sbn~! zL%t&KvI(=MIp!!_6@y)`3bERbyLc9 zP4z-;h9X(?6n3!?bAT>p+Ce)oi|De%A>JwY2py$I5~BfDb$fKao%mX62!9v-AUrCb zBT-1VN=fMg*=<>g43=Z^MA-%jA@rde;cxtCz!-Pu`|?+LJCp{aunztUjsd)0J{$sV zXG`b})XqRQ8HQi+#5lKDdz;T03u-4DSC|%>hlA7crDjUioC-T`d zn}w%}w*E=1>Qnbv!Kdpxr1wbfy131$tY#5o#Jh=|<{gHihCkL0+*8%q$R)AsqpV@Q zwfVxu+}D6F@Hc-*oE|hYnv5l*qr)a>4oU7I1p6QJfGbC4if<{_spqL@D@@{RSVQ;? zcZI#inc-C7HOW<(L5hh?(AB^|?+E86+a_Cg=L>HFbp~1{NC24Rx%i#-PsYF=ebA0fc3IdgEX#AW>R9pfVrA`2a)B&6tXu5u`_mh?0~RlicT;R7>>6IWWbSfG`JvA7}Gh*9-5*} zm-a(<^T+wt=nnBhrkrh=X zZ}aEn?)b9#^ZqZ3zh3@+t{|&&t*cJ(Bwp6KRj(g?BDz0sRh5EkuQ3s}FXg+7j3rHs z5IJA6F6c+(tk|Q`Tu_cg!fzz65|#8(tchwss5k0N^q+{rV1sIecqwv-p9i(TA|(fu z4Rt?)s`UHRd!;?mJZ3hz6Q4@%V4~saf?)A3@j>B2WI0<)T=V?rdf|NHI^_)w2)VOp zjwnw0mu#=pCP5^2F)leFJFHl%Y^^$?JS1Nz>4m-Hasxm7cYO=|n~06{LB1)PAHx2-THs4hw!H##~$ zh?V4WhXGp~P2Psq%f+GQ*iDJWi9zvC!#k;u2rzCbHHxm}?+PZ##OftlujaQB)N?^M zehxJX@b53^ZhRB;m*9$Uq_878fh!^Fd#AaYIG#C1)vd!jF(C*hS|zzFZ7yvsxhDQ9 z-XlFI@2^^>nXNTw(p9}=gn;JrDJxF-?tvcap?g7{uqQ&hu#wp9y#kNAA%iznyC_bUY>3|i*`4%PQc%V<@v zYgw0s_KA%PVa8?(Au$`9je?E#zyyxeHtFC2^Ut;bMX59q2w6oKMA32 z5Ro6#HSS$B5jse7NNj_Ust<1`~x8d;`L3Ma9zsZ6Rqt!AZs5fqAu z0jFF`EyjyH3*86Y-#xSOXnH<$12c(yl37xN^uBbwY@^(yFsnYO8TCUIE^j80VNbap z6ocdb*2Jwq6E+=QhYb^k3zuL#yo}pIg%JXu((_MUz#Zp4D+ExWXh~omLDm4 zpLgcl>Mt3eD?TUX)cx=ro$sMV(Q{E&HQjjN=(q;zKK z##+S3VY#~U2y4vo=-3dQ!VT{Uy!9{l52N-Y<7IhzF5*kfzSyTxokAz63DH?t%)#6v zXt>~r^o#PErlGb*rI#-ex!_u6QXrBXOl|>aU@&Lkqah{Vl(|Gc_V4i?@Cdzk{V`M- z_YHk363KQd_9zMEa%CH3igJeHjl7?HstlJ1MWfI#=rr?~x*PaK1_vHd*Vx5yM?tly zhvb}@wRd0wx(ZWK1vKg3p4eXSBUukzy1Ib~`{zlgz+Z9@w* z3DU2~VK$y31AlWRm{(S*of&G1xF5MVf(W^!O;_|1o3L8sI5HgTCfpPsSjPMkF)5JOTZ#UoG z#F0hT>l0il?Zf#!t!yBFiB74THUEo zGU7|5D?B4)uC_?NR*VQPAy<(H=pMm%QKsao^tH5BQX^U=C`KOgxCN3{>MF`6?u%&>nt-+)H+dYtbfn&I>+S0+ixpr&S`Zuk9lS9o1HC&V4I$EQ-C~%Qct_7BZ=0YOz>WqD!C@Dm1?9d#hZk0(T~tbE{OR>)d#q3S>W%0nz}%>p&|nJh@<#WKjItb z?do0R8;tKJm9&^U3Gc_Ih&+;=ie!ymhk(xUTqoA{P<@oUB=MqESOF3W8=&X#d}J>6 zMIaR262251#Vqgxt`*f3U*q}Y+-=)wZe&uJ3Qc+DO0(NM)-<7}&hVqOQL(C^*)J%s zJTI{@q1;uQ<{CsCMltQQ=woTNbZ_dd#DET2KuE42_7GOGClyKO(FN2{iX;2uEq$`OagI6G#istXUuvG#Y^`Z~%0XiR7!{wIWnW zsU`Xr`sKPx%|d0cR3b=(#Q>@0LLHHbf(&t*{JwIS%B<`y3jjvJhdPm0z+;mOe}Qkn zzhN7!M}{E#U>X_<9pUx7lg(ky(SxYk!0iAT$fC*uGXptfI+;T(AzBe9h&VDV(2;sX zFJ@!;ozO7Y4v$45P!swT>nWHj=qU&nc(F=MB$z002u=$&d4BtE2i`LG zxpL^VK%}^&cZRkIn-la~Jy69cgVho0JjDqaC%Gi)DLo-wD4ir-F3A#g!BXKKyn=tt zC&J5szCIV3g8dZTmVT1SWJO{~v`6qSb`HIU=#g#kcKA3v2dsO|f<#bfeinC#O=VlL zGuSHj7Q2X5vCkQdEoQDTZJ3?3nL0pCr8-kBskXpxGJ|&0W0*o_4||<+@dZ#rpaMOG zry!$ICDscI!XBY}(becd^dag)M`KU1MOZ`ZH+l%|i*3jDVmj;^qJ@9*8vs+@i!BAp z(_wZATh2_L&>=fUeasnf%Gl_1D-J>*e8Ic>dZX=&WTEX9PsYk=M8*oC>1V-+avXmU+^E` zqVT|1;7PC@>JG8|2A<@$a4on6;1!FwQ2sA|Ca;11K%3z$K;=sZUbCUt9gxH8u$ibG zzKQHdcA(eL3xM-V0LX4RgE1|bnT(Q+X3M}`olEbe-_R2nH*=avV#LfkCXL;|wq=L2 z&DkC78P3nW;x7Yl!d89{SHP}h&eBe52la=VM}4QBQHhj2@P!;kItdd#08jK&-shhA zb@$w5u9dFFt`wKTeaO>@c*(qmX)IgxRU9l;$!{oDDQ77+D;W6!#b+g>!qqwII#q%4 zt^5k$_?5!nXc1frZGt}`yRfZ7i%2D&A>su4u>a5p$Y4Z_l)@-tM=H=9Y=uB0$iX@R zwW=pj8NQ$nBnbHePIG6Z88Q}V!qJ@nRv#B3}d%&Ml z6Zk-hnBDA0?h1b$dJOFW9ts% z-??@CSEvp~(GWBgDTHS7|8Ozf6mar)(<|v9CYep<4sj>Aa`rEF2-}7o%yt18uHf{* z*R=|0i4>m;B>9#=$kXH% zavoVh{7p!RPxyAc*st^d<%{qI`@VTP)opTLbsOp~d)N50iNS$$^j&5cvmIn;G}9PV zv!mP*?l(IUy#Kb~b97< zFUS%Vh;zmHqE*5^0#eXV)InS(Ixg6TJ_7&Q6#W}}iV}z!>4|&-%nQd`c@JL?st3P^ z2J)A=DwYLYmy?t(ajwA%n0ZF7JUA$g63@BXF0Y8w7 zSOMqyFWL=_L8qc`kwo}3P+o?y=a^f}Q%1oIqD{a9_7~~L3I9bO;qB+U>RaiH_bvA| z^pEs!_j~Y%t@w% z8N~SLZ*&2DiY}(@%oVm7_lj%4g|o{6tBS>8w1R#Gc$hULLBD1o2Jwd2aTHT)(X;ahN8_BQ<=6-(6wP6V1zv*;M6 zIkSka33!Ms{G7kSU+8!Fci=^M3H}aG1U-D7Zz9laUgHmmLUMQDcVHl>JPZ|}7SLYi z4mTDmg-?QWf+MR@0!_gNW0$dx0#-0ZxL8;xNE4g@4%bEK8$=0IzP<21_#o)xVW2AB zhh9J}-~!+-euSvdG~g}1jqL)H$p^tf!7RZ}L9~z(CW~r?14PqACxkx1N6-Uqg6fh7 zvWbE@C=qn0iJXM%!ro(AGnvdCQ14gLiPUd08B_?GY!*lgn90YakTl{#Ji(vi%ku97 z?$e__f$xa#u5W_3UtPGXjdQE>p|gRrhdp4KU|wKKHh!o{s~Ks$Xy5A11ukE`r`p}g z7s4FI9AcmNv*>{+N3vb9NwY&A88Rz8C+a|S|EP?}ei0iY?2)~qWzml!Z$#{kXdjUu zHYMbVexvq{rbIJSgQ>>Kc8fM+3lSbTO2z?yU=ZkYSx^p8H^0+fFo77TUz7`AAA;-| zu#pNffk?*x_51vL@!Q}Y8~_u5%eTmv0CeGd-f2E5o=?aE7Xpqz9B>=Iq;Ih0d|yN% zm?Zim4oGfD*UKQqLuGsQM9mw`C(RelbW#l|8* z&@VO@Xo@&+DLU}|{)RrU$5q$5?y~!ti*%Mco4VBQz3vK^!6|YcaFjU)I$`Gx$6-e= zhuHDMzQW$rUTo`Y8)VHjKQkqoJ{z-)v9(A|Rn@)9m4@*ZdklJGedj{|(ZFT0gMWuV zo<5DGC=Tp`vtCJ2SniDgVW+c8%z~X1do{za3 zJwLKz*udZ?x+2YVbuHkzILSc~j~z#Hpcech&dpWw>mdbDt)F`dOdC*Ty@^)5&A;aNY?2D!h`23=F5l%u9AOpAEM_Wr7|e zgQSOiwX(N*tERbjnf8vhp>BsRL9Y+W49eDD)-G2!P-e)-Npr;agi0(3nF6$|Hq3*- z8QkS{*DZA)cHMJ6b`;nxHpG@@{cVw0XIc^4LfZygs_mAw9&k6bGzXc@W~HUfd=>cL zj~GWAQ;bo@3AJd=_UijpXl0e*P37#Wm};!Lch#?|Jw}UjG2x@)XoNmb4}?F;-s|Uw zio_QD*pX2U!gd9X z(|ysjR!1m5NQ;DW>;y6%_&dh&BJLnlkJ$*S=2&_rwI(nRoS3ELP7)_36T!rF9KoCT zkNYG*&#&)$?Q{Ab`DXa)`&?eVFBho$M*INTnR-G?*lye@UIMuHEWserFv&DolH$3t zsk*zyp=qt1sV&k*>LvreV5M$~HcZo2RbSCrHd1m^bYGB;wuE=_JJ{WH%fJl0##>%D z-u;j3U*~bhGkczmv9`C`EIR8XYmK$HZKO?LJ7U#YhgrIqdD9!S-~7US+`JP+aJVtf z7-C#htFPHwT~HNU`5XAN$5rX8b=5Z~K~znt?TjYIjxRstc8U zD+>%q3}|I))wb$`H9c#~Yge1T*su9}1N3x-X6bakg=nw#eYh(;F%%BViJTQTHF;qA zkF*(S;>@pE|73Pb-j0Z3Cly2wB7lGQPxC+U_xB6Iq%qmw#JA4d z5%i~AI8@XD!K%Jp+s3&VqX&z}Zw2bDF zI#T&lwp#W}dRJ@{;@C{&4^+T^WY1D9iN5~+zR8{w?p7|HqrUBeHN~1?>21~lji}Ci z#ysBq(}bG3nOM_H(?jE}+U~V0YB$tAtxYk`2D>Z8)hla^HTgA9YI1A-sd-g>v-)t& zuG&#X%J|6C!t%rR#`VjW6*x}sW3F-kp+}{SGvp0 zBy z(jR|s;xzd_V5imsPs$TG9Q};G!#~G&^9~rNK4g!O-eB1cb zw8Pxm($pGa`)1$hdgZx{r&6Dpk-QF>BA6(BsWt_B!b2k^k><#|F>mXQO@p&)vqG~R z8N)JmW?-2OGtXsaWH~bR8HFk7iH+i$#q!bXqYj00!QXX+`la%R+$(u09F6?}?!7EH z0eZ^!m6w#d=N!}$k;}d~bIms6es$LL4;r+c)Udj{jM0yu^<9zY{ z`gnV=dEp9trN6Nw0rKjENHB#kTO1|5D6`0$C<|4sH07GM+8f$1-G1FuonBX{>7xFu z+^dL@r%AQq4}$S14FAoor#F-5{Byi_>(07*IrKKEWvZ#Oacb>@8oYXF^^oe1)m7Ek zs^?T|!H!Q#b!qkd8cR)fZTs335X0Ry4{P4lq|^o(7aR8)zZkcIYN#-FG3rd==9lIj zmX+2mwgZki?o#hF!b7cMgCPU5L+Fr=&_;zWh=`7ijT{tpJeExyojxO&E&nQoOPglGEr^dB@9 zU4~@AY5Y`n7np7B^Z}Zu+EeQS9bHlU%!{HmA0kU}K|B~FTO7*iMlhcycc4L+zhX~rnSWkJarZ(2wNtb@&9l1k8moz9C+>C&4?}8{^&TY2jJq z;XJpzn|x#ZgYn}85?DjUFke{*zXI8Tl?omUw}{dt&tx5xHdT~*xJsxx3(olz-C+F< z-A-+S=8Fo@_KJIQrL0iAQy7f(2iurtp!8VDXE^4osvG1EcXe`V9lLG6EKSUZOa-RN z<{p;A7T)}q`I~8;>71#x*=L?&Sz#G%`2xDoW7B-ozrd@Z265|b8E9EvEz_)xwDtEzN?w%An}no&%c2Nz{il!f_c&os-xOr`g6g_;ex1F z(Qjj}#omhVku)wXIup-0ltw4dOIiyuv_o>cByr;VgxT>wW0yvEi1-@9>$~bQwcpe` zl$&Jp#4bTB7K*+?#vzA6$NdXh#iw!A%x}7cYDYoT*1$>NOpFH1%mO?L|HpsEC-zl) zZC=J}_r3=g>0JtP6vEZS0P<|0E8U3g!2_2uIs$_QUjze0UnPs={ggkH?Uc8{hQxH$ zR1KwVpqsAksHs$4RGwFC2e|fvWUnYgFdlip?`1dAX9JgsX#WEbT6f2F$GP93v`?@; zH-9#LGqnR6#|leB%RVz=-fP-pg3Y(h{VcmIJ1p^*G3E->Zqpi5HkcqgTKZcCTb5YX zS=LxWtWT|WYfsyFTexkoE#BVKG0Azv+1+{9S>`_IZ%n(mbxI4gfIJ1Y$V>~IUgZKMOVl^sM+3Iq{e;1KxgUg#R? zthGb7M`nqspK-2nu*qoJYl=3#G+r>qnW{~F%`MCW&0{SGtx>il+coQ3ODoGvi^lrI z8fUv@>u#@aziw-5gKS%EPwd|u)0`_nUOsdFah5pqoZFm9uFAR|_;qR!>tkwI_{Ilht_0c-Gk06l!*wCx9w&%uJgr zErj)xZMgl5y`H1WQSKb*+T$vA(XOuUC+_&V*>#iZQtC{A@rsjTiB{tKAY#V+D z^e-Y7u9vn~d9^q7hk}AaO2SH_2FJxENa~%gw>)uiav*grK!`I^!jj7B9jV9Edsr_k zK^*rr+83#fY!@*;Y-R8y-C1?KvRqaonI<}f4Mv`V%4y<;0S>wsGaoR}ovEjR7J;?o z6(Ww<1v=0vFqd<_PrjGFi@sUDX1;E|sbB-H$~VW4fxPWQM3I97+o)gkDB#T01D5yz zf}?E(M}?(GM9HZ@0dz3xIPTGR(t?UB(Roi`AlD*V!19|t^S?wV0+wE`d zogJ?nb&f(uvE!3tmt(YJtmBE}Z|8JZ12^j$=Sp%NaP4-#uiM}W0eg0j-1q8O-+HPE za4u{Y>=0A~cJG2XPd-W=t6Lgm2pJnOA?8=kJ16@~CX{JpBH2-Cxb(V&7e|OYf_UD*V$g%| zTi(Y`WnNG`Ih!E;TYc$Xw(dGWkS(2C9GIib{@%XdzRJGFKH45>XKbPN>-N`R{7|gESZ169fwsg5jcZvSzCK+N*jZSQ%a~x@TOM_>A}_@lE3^;)f@`OeT`M zB>zlmndpw=qx(fkBS%CK;orkbLXHLP)WO;@>br_;X^^Nh*s%MA&BSJ-DAFA&_&?>n zg;$j6|37^9Jp)5`GjvL0ck8a**kZei-JQ7V>e_2zVCUMdiG{5oqI5Gb-7|Oo-k|H0+;=5B?IkeP=xCj8xd7_@i-7Siv}Ra0 zTAF~ny$zm+H?_0rkW7+~mhk*uSqPy@*k!~onCy9rUd7jzLFKp&*G?X{-;U+1vQ_}F03TXbH! zTUxDVqxz`YQR}RsR8q}M-3oP)QVAz8Svg3RsCUtJRc+9nGEC4cRNHk&0KdyMjDd-- z&bSvc=T6g2i_uzP39??ZCo_v|$@bH%oPBJ+%>FKfhg=LA z$-JPB{@Y=%^oXQ@9tQft0aQB4;(4H2j6!aUVPa>9qa(Op?04oN(}&q)KW4jcjkijy zsn*d}%9?FSvUIVySmG_OEnh7IEoUrqfeUoQ`lrp)o@I|>7P7fq5Pu3#*cpIXRUqB4 zy|@wYKs+Q~5s!#S@+etA#!>~8g;G!_DHm!Z=}2}XMgeDB0m>Z}ngYFUf;d|!MFH>M=pj+z-_1k*z6zC4`M`r!oA_bp;!R9KHC(O>jnHO6O7Q*UpO|uTQ z;x@CbC%mJBfIfb-XES5j{+u7*lTYS1^6&Xl-dpG*^c9wY9{eAnA1E~AgoAt#KS1az zUP217YFhlkQKNh2LjpQ2Kz!{iI%8GamF4(bq_xKwNr z#tTdNC7g~eWw)@OnP}#qJ;`2ZJ8P@4U9tJvoI!nNvFc%Ee?XUd&DO@=%f1kNP|BG| zHka)Ozs*`+%`XyYaf7GbI0l?+R zMaQ72s0}%fj6;$U8S+lNDxMNgh=;^k;3wcF&Jo9oa9MSyabX_Y``iDq^|#TsIO{WD$^2$@wsy2kfnG1gvduik z+}85KvcxhEs+#5IR`YpFw$%)$XEb;lM8p2PvP}kDY9KR)*#kJYkr~B#3J74flf;f< z7$O5q#vhx54Cnr-^>1xRoX}W{p5a;OcxY04$$18nS>OH-C!5m zBDu&=WD|ITqyVQO6X^rYgT071WMdaZE84_IV!cQrR; ze-1baQusVt94R8OXZ;|D2aCbNJHDB3C)j|w@Pog=SMZ(q?OZkI4OpcoM9+QPdv*%b zhn>f|vlH0@=6B{0yNU5&arR$k0n>r)&HTgcX4lyrnDy*zCX@Tj#jyjKjm&n?d0*o% zaxb_G>>Tzo=Oi2gj>A!I0kAh#f|e)(*(iPxd=Vey9-4vm#oyu>Sxs~zZow%$h94wb z=|W&d$4c5tu27F?KM5`UR}w7k3W{eZ>0P>%SVGlH`%61W)96Y{B;=HbWS`^$6;0lO zX>1VLk$j4KlCH!CoW~v_ebEERV!*fSkpoDp_)J7W|8_<_{LK`P!9!bG#MTv!YH(^33K91c_7^+>K5D$ay;j1V)$ zgJL`~RopK+fYQGSc0wyCg`VOTaizE$cnN1juo)10i`#{5pyRkK^5Rt?Ufjv22x|Bq zZ~i&AMQ8-o_jJA|yB|(Vqi~o{VqP+}%mRKP$1v~MJjTKP9hmibwimXY%tYv>y4k#J zos20=CYxctXK%3$F+a7BW0u${rixj?uVJ^b5#m{xD1X88L_blEPRIS}KdBI67rue^ zcg&H_aJ(e#>G&BUP_knO=`W}EuBk4O&PC269d|kGaeC$y?>yBZM7qFXgku-kE|^Qb zB8Et2O0QE0?GBZ+FMb1e0bdedbRG5&zD*n~jz@M1NyrFLtGKY?m`l9nXW-Eb5_6*laM7W;P(j6V7)$xUtw*s#iL@gcw8(N4vRXG5iWt= zAqiGD9r!n;;yUpUF;5r-XZ#j?_bXuxtnObBfwl-fz>f+;>{qT?`WwbOF9&n`oqXS>uoZUBv4u=7M`s{=@H9V#4a zWosqJsf9#ea6O>uW@;jyfcatW_`k${bR04ndx*i4Yv-ltIyW4?pkj(D|c1SnyYr2P6V5U7o&>(B!8R(DH!>N0NNFk;l2Xp&#Z~;tMWB-a9>I zo)0{qxgK%xah@vM?R?AeA}Fr*k{f{|(Sj@jCEpk95FUX9u^+e*NIM~m?G5k#6g!8p zF@g3y%mMbC{fqq-R2Gf){mfgo3EV3R8Jr6c`-`o>??@7GK)Yzv6S#US(8u^Cye;UJ zo?@|h8~ihN0_%-MVGF=3>m3%4-bLzA2kb3k61zkG{Q^;cCb9!LE&dDMM(JW1L~)xa zK@uUa^hIVOJF4%STnu=DrP! zTkABZ6^8m5`T^G8)jqAmjB6RQ#of}|wv@YouEigN`o9h3?bOp*?fBENuiFvdEI-C$ zf=|zo0Kj731%=2ff=hxdq1VDHLcIKn{mnuB{g(TD^V#XO-Q%+RL$_TnQyjWDzJdwS zYVrr>L>s6!L?K!!_C(L3Cm;fUX2)?4g&2Wk0&PPen*=eJ?7Qqsfg2TXSK1qxiS|lc zKC=v%PkY!Jb}heOSOxjxl<-cpAS(1W(ujn>1n)NZw%y0h!iulLPJqI_6&PFp;`8vq z*c;RfR{t&99}Pk6@H|X}yyFM|$5odVLd@!E^BinTpB)1^t2wSbr=VTt%8O z25W>}@&a~QC~6k_irG-<`0=%DAu#eXZMl|S&|j~&E;sz9yRFYReAatu>XpsV73C}X zH}+B2sxq37H#RnIRkUk~Z8}{$q4A-DX^O8etw9dW$}{9WE_VGRHQ|0C5KF;;J%XX+|Cdr;jE9muAj_aK_<(Y#gZMjpjyb?9 z`GL$@d#HV-&1`>T+i%TU`|D?~35< zo$=i3dCqgHPi63hu)OeP^82ChBCp1Lh&&$tJ#22&#K?-!&+_ph<$;R=4+gmU_4fAl zIO(?AEx_3b^RxvLADBWO!|&iqWD!3FDuKiN5Qb#3*_U=tTfH^f+8y|EiRNt336HVt zur^rQo8Foc`w&}^rNyeZiT1lNOPR#X=hpC(#3FFsxGUU6O0lu{D9i~nV`IU$VF{5$ z%q5-?ugE~MFHsM^D6fIXn}fSRMwa1b;9&2AmHiXdA@d-faN=rU7<~qoP7Z4G#@s@D7BQAMj`t^Sg4!S(XYmoR>IuXf%#17nPSQg$hi_(&*}K3=A7JTb zD%SPa&C|zgEy`ocyDfK`x-_brhqSQu8Q^KLz0R+WtjVihS&>@Zug+FAzY?jOTYaX% zUSCk*QZrW7QP*GN)10H2W!cIcwya^!@axdNBu)>K^p@#8u6r}SuYHdND&>vxmaykh zlVeljgviW@b20s5E2AGqoD5$Q85~{~%m)k%@C+F0pW>D4*4gE`^AVQ;j;<6<4WYqg z2stE-f}Hao-=8VBj|J7lS<4O6U9;X&ZI&5l88#bTOzx&E<91_vlb?B*`K!sWGpbjvhWqa19JzK^f0oFd_hhoHRMyWlpICPAQQ+%>e+EVMuUt|b50Oke`SbMY(xNVs{0#$UBZG`z5FfP);Gi;}}Nhj>U4OH7c=dl(yQ+g~)2gRcxK@;ujjmW)o?rH${9RdmdAq8@@~)NB8f{Hf%dMsq z#Zk>>!z}A#+dHN`dK`RG;w1jgcfCt}oBXALO@R@Sqhfc)bpoyk8{ameCO$G@VZ1s{ z9^X68E80IiQ;y0D?!+#lGx>_FpuSQ0@VZY$(g(n;U<2g_dwh^|AeRvuV6O+@BQO_;FDSYM*sfLL zX>izDF76Tc!B=*1I8ue|LO-H?z@_pBzJd6cxI%hS*Qg~>Kb)s$(yQr@^lQpaB9xM7 zi|XYMREDh3VB7ZpY48J zFH!%vP`d9&)c52fuOC;+j+Isw5B!c*e^UJ3ysfdZ=4A6~J!uVLLx2wxM0}?p8oN&O zdKLI7WL`vVL}B#7_|k-+-+M4BitsF`&-( zpyzLH)0{nJPoxIw5xxMN`tAz_OoeT`b%%AjwToFaOx5qyEz?DV4tAgRoVHNwqnoGo z)b4?&w6h`I_|7=Q6l9(bj-EI(4myh!d^*fp9wGanqLe^?>`v*(KdGs7H_2qlK*@9Z z5?v0CKx^qZ`UjOuErtm5iUcZJjdpC*=q8D-#*?_hO z_U&wld)J5+q)0l^TjpKPe?E9{WccK$v55|e70`6}q@Wpt zG7HoHO$|(mOy=7pCWW^-6*oV|J>r}^B_zlHfls{`;r_(=n{1~vi44G8kmJHIVFBlD zKV%tex^3KSoNovKH0h%zS@TKVOEXS8ReMNdRL|AU)`_|b{cgir<8za{MPhwm-EP~! zp!^;1tn7*21C4+J|3r4DifIL%NsvnEs30>!Y5r>}t9N?fh<_bA-0)dh1Ni!)@-=J4ckj#@v zB_R?m-IcbJQ^_s_1rBnL#2b8P_Jgg?ikQb49CgX+jY^?qS+lObwzf;{hU%e}Ps?S$ zB7Y|T%>SV+UR4}d6jT&ibm)uq+r{FjlC$4qibi~Y{PSw9N3&K@rvBJUsIMEF?QMy# z4yR;Q&RS=)JL;Dz$71dAF3D>W7q!u)J;~_ZuDJbzcC8ur(-KohrwmH^oLCJ^s=1L5 zLVgRJ=i}qO!E2FQtW%TZ2=NB6t=?iZ=gf%KTyv3WtAW#<(ig%xUZ^9q_38xmO|??< zMEgy_GlTGK4=4UYeqj-^DdEOKlx3 z6{e|%&)UW6XyuHS35xkm>*_bxcCYrSjI6v|{_R(vpD(_reUB-wElMvA|F-S(z%N~j z+84Jed03oS^s#txrCjlcPNF^6T+kS(p2+=>`nk$oqGd;=X6Gq>JELbL7pI;~3XGc+ zN2dPh@U`>jP6h3*q-m1hBn2fqr1nkW5}!oB4ZRdd2JpTLuVL;5&WLOzJro>h^0@n~ zAG_4P!jfd{uJ_h`)p%*vOZb=P+x2$z}F^-IctAs zFJw~q5in7nhxdTFtO@rg1u8~TB+Zo$lWde^Nj6BrrTwI}l4Nk*bfTV;#~?TUMkWvh zJ|4S=4oBnAFUSl82jne8RD%biO6U)f+5~gR>xc^3jY_d8XVAlJN>I1zHDMicDP%@3mLd_mx4d3Wa;~&_-qbh>0hOaA4f_K7a#c=Tr|Ao8S*XE23LKvdYp;{--mJfGQFF= zM6*O?R9)5LrqR|o+c8UuX_zV7vV&P5oELY(l<1HUg3x$0l}wMMF`6g0P?SU=nI)~0 z{3S_~T%{*~BiWzS9Lj;ZMwWxRrXKeIrPDjK5A-$-Fco|W6Q)WQuKAH& zGOA=!Y1f}0f60ITS>jUqTT^eN)lzNR2R=1kx_RtdM}tq5|03^|E`%)BB`fqrvQNiu z9VWF2j?RhsoY*gOU6;dMlRDl>CZpem{}yG9Wn(`?B?Z@d=Xz{#?kSt%P(>Sv^&?J})|y)1G*3}XRAuSx;J9*M|3qz4R;&9NqwF`?YfOW!)e>NH zV7K#yh!Gov7lRX822o1Bp@!2h=%p}MJR%({T`WllZO;q(3go|hTBKx@o~VUx@&$ei zPr*~MY2fw~g&4)R;(y{Yn30?UG@!dM2Kv$c;CZSPGC_~!j2s1|=x?+Voq`o%YoU7l zOdKU|k_SkR_=iY=>TweI9d#wXV`*qFH^M&YlXwYXP8&Ffm+WXjzwOB^Wj@`Gqn(SV;U!4vT{_)U09c4M1R z27Zc#&*finBiSGJyVf<9Y35GAT{T5zRrOc7w+1TOH*IRX)Hu80Q2m`+ zO?6{cOx5>_BNf{#&X(OM>sw|mlU9zd3ah+O)u*{gV=%wB)|oq6FWXwVeMFe^F|VS{B=D--4|U%hsw35d3Zxd0c@R@#@mg#vI2yf2 z!_kAFI4poZajMt@>W`hm6k)iK3tq4}LN-K}qrwxR1vGL?0288-xzN40MUSHQQ661_ znP95u4r;x-aHqis>@9W#_`jj(G-R(R2y+D;|A52T5>SF-;2P{^y=L|?xqv2Nu}-Sn zs=Wd+ooU_FdZYDHE29|DR8W7kE~zf3_K%vZYF%Zoiq&QLKR5kE%O6z`6DSnBck2J>Rv)F~;Es`37CeXW3FMM?r&e(y&f3Za`X=J8{&z)0z7k!7%sAa zU7iN?a;7i{_(8Kl@q9>lEMVerF&`%38OSQ+6VeKi<}j)NFQO3Gy|vgK>E-P5evl7JGrY2pSZL6|=aQrKT5#yWm+eK(|yoRAW-zQ+{t<)G|-8 zqB)|evf*m|kvh1^pvJfQ@2W=?jukV@cKw?DYj#;_`K|Kn6%AD%6dg4fFeYM|VnGnc z5ORm7PAlDddP)QS2wWh45Hqn&X4?AH^{M})U&vUQ@g(C=+W54Eshg8FByh1?V;)B= zlK1s5^t8Eo%MMA(@Gjt{k!Me_87!B~jmF-FjXIlpp9)uRP&4Yu>aFT$nu%J4F4(Ze zcm}2f==qOZ{gx(d`~ zi|I7Fl$u7>0mtPMK@lrpHuVTRcSEq3plwe@B~TUa0$jNSYM(x$54hHT7v2DJa}H3j zM}UR70q!$MTnK3B7tsNb&Y8$gKtoRfa&ZNAq8j)DFX3+&kUZotG8riafBOf3q#olD zeg)^j{lQLRE`wjKV4G_jZcVTZGKZR6jV}zWzFrrrV>M11rK%k;`$Ai@6$_ijG;U}p zs84`+A6z>hCRmrNU8+x1RaSnem|hWIaj;@%bxV`GD#5VQ_7~rlm?$|Yd*r&%OTY6s~8 zte9a$HRxfhv59c@`=M&&A~Fq`j*NwSDFOhu(1?|QmrVhjO)0zsp2Hb%UH%4Gj)NEn z=l@Ufrziu&c_@;DY=K=kjBH2dBV7;)=;FV@j8XuU`Lp-~H1ekbJ31po2wnL|ZUQ@l z$+CX}=KN~lDF#_Ko3lXq*WGl{INmT?|5Cde`sntmKUycYTv2RmzSoQ>vYS6Nfli>Q zzA>v|cK!MKCv~~Cp|wIyN$sw>oVqcMhgt{gE?A6g02W32I8Jxj>^{QtyVpU#6@mF7 z$HNCjUrx{_sZ(MyhPEBnPTuZv#y@q%kbh+;Mm1eQY zLW6ykWgDoiExIq-?!Xdlt9hV_g|!dVCTbRFwrdD&cil97o#Cpf#8PSN#%|+N!~;k$ zcr)w+m*H#pIO0Arf$T)3(Y+*sBwKo4dP~|3ct8P?3G@x9Ydp!bLzxA6-9SZMRnsR;^T?X*IN*04_GCxS$xP=%{d3#3*Je>JV>HBDXxB2SKv%!O>IV4kTE!FEKGu1d``d`dx(nxXJ!Cn zYlMti16txkpvphbWph)xV_XwAnlI)D33q@e(^32#5T95P7hi(jx(j$dedO~2Rox8? ziLbmP)crGs)xs=LW2^b?!05Qdb%(oITH)r11a22p25Wc~c=%<(&YAgT{6X$-HVe?i zU)EE=<2wOd@_&uDjNgopj7yD`2CH77+oG*e$EzlTvuWSvq^8x4e>UPxADbGQ`?fT+ z7OM7W2wjN&nLf+V&oIR>!!R1=sT~b74MCe=hrSEQ@vd`CcDzdlq9l*QteLm8 zvFtKunoA(#J~Li7?A0ge>cLZPy!x!VP%~V2+Az&L#ddhe+;9&Pz5) zrb-4#Cc>OAQOZdlIV^NkJBG-VaEHP?hiK_>`X_jDYye*oJJj+&p>nqi?IET-gPphs zUXNwMZ^BLRy|~NG;`)L@{vs#ixA6#6o?l_=l_quu7hc)__yAD(hYMEz8*nsk@b`de zW9B0uS1*PqXb?xv-z@ z2jMo5_Lg+>QqY4|7|lk#@tJXiagSl2eyHxT#zEapxw56D`9{<8#wCq!8>cr-Xg;Bk zx7I2P)FZSPbPM!;hH-|0hWUmu@VO5tfGFca^BY?R-xvEz&vFvnlYAqBs^p=OE2A&R zSYmQwZbzp?lhJLWy`r&gF=*WftT~QxRD$UtVt)((!S){fa^>Q)THkOD>$13z(lfKxFjqU1_%j4u;334 z8_Dp5jDTu&hj3Q73pxC{un!_u1o&)h<)h&4tjU~|D`npT3p12k3eVXH{v!XA#~_A1 z1E$nWZUH-#X>U)rO|qV}r2ij(_=NeW`J{Ow`2Xb@5kps9kj7sX)w)pO2{+BWXhfRK zOTGS5E?>Xau+8w&aLf>7$OFFaR9&66L7!zxwyoma(LCyn<88M^-dNz7 zkjOAY`0j|b$byK1i0=`~2rLqdq@w0TABfo=dp-7TY<|q4sF&e=Lt_JN;EEhA`-^tR zw~AWsEZkJ{$=cWY8B{hh@Kjl7`olQDkfhJlHEAzu?b>g;&W7%$xt3JBjlCmSkvN#H zPosL!x%79~k3w+1JwfZ}-z1ME9@6E~$MCu=jR#)%P}&W6H6w8!%nrE!5xA{LCA@@Z zW1bb*)Vti*X>Jj|`Euop9;#-?r z{90-icE#A1Uah%GRGqKs2UX-O<0VsXILE!sGfj(()p`fR3BzvFLhCJNzu1PD>|l4v z_ErVxL)M2UMvjbRh`X+s`A=K2*^3ArB9WI!_ zYvc^sm!2b$NP9`6q`zQ(`3i3|AY)h zaCz)hwlnL&da*I=c;G}FWw*0Qz{6wh{`OS3nP~|qw6~cGi~+_o;IXp7aNRK7@Ko=k zAE@i9U8z~Do~l}|ENQ*m`l5BNa)fHL`nkqQw?}`~@XWZ@^vm=RdNG4>8DOK^%-5~s znX~*wR6(wHpk3~HRQd!4=!42baQQO%82M0nSGhhkH*{|3)6iu35BY$wlVR_}CWmd6 zM}>9@o&;`zF`mAzo-$v_N#Ynla%`iRsoW4D86mMeoP?eNho?pfmF+`%J>4H}srUtm;Atw4T1aiAGAUo`A^3t- z5N^ae`~tX{^hR^RlVTyDr`sVa6@x3zpZru^bo7X0n~w6m|fc!P=QsOs##O{i!Vt6wN8t z5=#zn`k$KDnQ`-I@D-bCaM6F&e$%McIco5vR&7(QQN2~|g1U><#1$9?UQw$wGwnjJ%Pb}5jZc|w*TyH*rS}kkPi-cvEUe(NNB((SQ6q&+`7}9_Aak` zGQ9J>cYXiht~IIE-PP4~PVMs?+w$xT?c1wY`e+FHt?S61f6iItuZAE92FKdY;A9m9 zA&?sCHDJKdZz}NpzrX(w_z!{q5cm&){}A{Of&UQr4}t#>_z!{q5cm&){}A{Of&Zrv zm^yjU1VaBgFbD&m2=HF~dp|2M{~RnR$%5lo z4bAVrYWY=D^WDFm@vGdg^MCL7Rq|I&&2{{$vHAVq`gkBqv(KdY5B^622uRQ@*}sxB z%l@k*EzqFkzu%fmLQwOQn%mHPf3wHsf6Fz?^Gn))pkX~aLz{TB}$ z!T~0~Q2F0lx&NyTzgp2;)Bl!kZVUQPsej*_>uWCmtChd-`nNxRq0o%XFNFWS-i*aB zJbua0EDH`1{~Z6@PXcHk^A9GJU;_sQ&M9!P|I?_$*RPS%j0X;h|B*xdKlotax90Y9;K}xXURJ^S&lx3<|Mb@{gpmJ1 z^Zzdk4EnJ7nay`Kx2E~2|Fo@K>IA9oE=DF1uxw{hXI`F!8JiZK?y04K?W%x1R5jF{)P%@M&91^lX*{{ND&>m9wTevNJ5nc$F zg)PE1K`XomvM++n!ZGkn7%CKYL7#+Y&{4=mh=oZgL_maNa69;suu8ZC-GfGgQWj9c z1%A$VC#5A1ZmMFJ!vQ1Z;rylx?JPG^-XOF`S(#-pzfnk0P$YZ6H^sHzLC@ zwk;gPN5Bfav+x?)&bPyd;QdXV&?;r1b%kZK(u=4wRQflAvI~`&zi-gNa zF;}}~H z_#?U$^5t0cg?KI}ryE7B@N#$nHi6tEd{b4>R-FfSNNi{JTE+YyLyW!Jd>5}*XIoO~c}OSZy5xinr_W2%@QYnf#3D|!{yVI}Mv+Z%~He8@6Fc?}+9kV6L8moUJQ7D8M}ytlz{Jz9yi zW6i7%5pluXcX5AyuGu8LB>l?6NDRCk`M`FP_=z;sTDFEL;QDgQ_%}=hI)!}%=FNR} zkC2Z2Zf&IgQYeT_OE233@ez@ji)Uu4j)_p~ATf?PFw?Lj0>?Z?p4r>-HqsENIHNI2q>&cw2B(A#*Sq#gGKS0GM&TmHQ8fSAS# zR1cvQ@sjEX=OELlD!V6qnmWhM7S6ES>3nN{hxP<%zRTRj`$4PtJj@9lN?u2QgYwyn z4s!mLN#t-F|C6tj7sC5&koX-YXSUcXq9CQoX8*$`@&{vuB z{CdSW^Dv|%mach**U5^Id3-lEfa?m)BO(Yh%9z|Ft3(2OSNhssOGh#7MO(xwV*=fS z*aMd5Jm@5vLM*XOG7l8pfHNo?wT@baf=j&z(S+@)4vA?QlmS7@_z1yMr}YPwBrm!1|qr9mBz6z;T9^ZGf%-C0OtA0*b%amQOPEo}Nr|Iq96w)}kFJ39@BrCUMGCf&y9iwq zwU@5KZ$T_u2fx4*u@A@D(d>7qn{WgR!*6oe zm|S*&5Drg6x?+s*%FaidK&)#az~oDrDO_y8Ole8 z34VM65h%)qM?qFBOLP?q=c?flq>pf$X-WHV!#Ne_Lcb)X&}pcVzQTXKP6sEtv+Xb&GYhDcdl->6=k$ri^RN?@X9^g!#3xqczojik?gsnhsfGslIfb z^^WZVy_Zqix0r@oCK=!8vvdyn&${4-4K-J*wp4ttaIGBo^JjT_m0tx>cCx6TSW@w* zGP1g3Rbl0`dQ5*we@6RBmts1?CaQ}AiX)Q48v^tE<-xO}*0=5**Vt}*+mW%mB7GuS zMH<3>3wacDKk#Wlu2-$|epyd!C^`+E0KbPW&_~T0-7(#irol~42C-p*VT-YiInmb5 z{(;P9ra<1J1F~_-Y~|mIAk||>yK95{2G?SzEsipWc=ZeAG{rM%h-e9>MBw9=4i`T%O&eVo6L@r1F0W$1nbV_b8`L#w}{)w#qnwU z0e&*KhUrcJBtz_8*5AzWCd62yw`)f>e6G!`_O8mR{8kxJ)u!fj^{xs@8Bw;Wa$W72 zy5!pW>Yg=NJ*_e64(s~Yzp8Q6rrFYv`^q1l2Yq?>{hofIqhhLKsMg;*lqPT;PIoxf z@j<)vn9U)Vjvf)28&v4=P+h24Ej>cKK)r-VRA_26U`=oXkg=q1x)O+WCU3&8^nm=q~p7;>Rt% zbXH%gZLgiAIi#7U>8t6bZLhmwTwtHVwMRbVJ;WMmE2Wzw^}WH=*-I>QjdykH8uZoim2D~pmoF?!{yDvLSn2AYTgtaomQ?*- z<6bwiAzxdqtJ1e=s%pAo_+}hvo@r@eerZ_NRG^dSUNjEVC20@WpR8S0-JyDB<)eyu zWz{7oN{^J`6{_-}st0x78j>1onc?cyUX*vVmpCXsv@q;qo6t^aNgEQ%62g)$BpmNB zHa@uR%~q>g4Qq8cvfTfY=Wf+l{2v6^VqHmtB#OJ!#3->iHR~&9CB4sI}TPVl(q&}M) z_1Cly8*bN!)xW9hSr=M2rT(^Ni@w6ViY|kDh|egNI`nnk+0sesP!T5!J5wfINLUq5e^ zovm=G{#u`?%Q5^k_q2?(1X(xQ-%&m3xr~PSo!(+MT3(ujrZu|Dx?ues?en^_%D3f3 zKW7&?7GEsUmE@FU{p<-wAXPiws6vJ)$2+`sdg9sO{k!jo7AxD%@3f=Sw!}$E;-nKv zHJwg$%#2^u?sJ^DO>xA9z?SY2N{#fg$PX{%dRXe4wDs?**~&Q;k>!e?=gaadTUK|i zPN+fZ4Z3v8d)i-Eh2#?<(k}`x$L}tK-2FZGdpUWJ@%qcd&HbE9cc%#s1C=V7T;zx3 zamAF?cFgj(@n=(}u0`WatzB!-IU3BSEjDLnD$sO)6VH=vRJu9Dxj-J{y_S1ZUX5Ot zy{bH8JQ4SeE>4aC%5Ac5qUWfdcc$$&nOW9!Nz7G(Gy9bl$5zEoRou9A!@5is}$sa%9csj zN>maz@g-skUW($V4jvDCAk&dA$V4O`DL}s?Zx98RjRoSDFgtbv|BOXpf!Go(0`owJ zBB}6GC`$OuDY&IzH`qiv+1JdgA4XRL8q>_@)ksXm*B}>HqqOn94{uJwrc0z8!?cr+Z z1#}WD#M}5mLV|EaXa%JUCLt3V2S0|-!6dvFX@l@^TjUIK9-L|6OK=iA5Lzd= z3Xk~(ToLn{Zb>(hnKqeCYgu9*Z@OXVZO}Dwx*A=Y?hoAu{W+bt?t*T!evsjK({RHF zqo3K=Tx0rZ8E?IB8E5Hd8%oJ&j`RT-64W6|N{2I3nGw_?3Iiy%U}Q`qy^>kMSOAU% zYzuBI-v^$GwfqN1IWZjI_*`;OHe1n7ks*&)o>Hw*Ee1Q`EOoNO6o&$b5spV4ma2bK zm#f_!V$?pW66IE9z9L6HPL9bf(g10lbA!3dJY#+`K5Pt| z#ExT+vQ2CVH-=loz2?05qr8i7R0xAkK#{=eoQ&RqTwcTn%?2h(U_CM_R z?cwA#GKngtcG82G&TMPW6U1P=~48s5_`#)N(bU)_^N#Rclo-s`tue%1C9gVv$0oI4^G_zby-vZILRa`vKmg z#WzKAQ5-QHe}P%iaP)WN3S0$wKoh};(s52)Pxde77Trj7pk|Zz?6`f2jkd0_`dfcm z9$TJRDlCCOd$U#-wfS?n2kFfW%kF{^KKeCtGRpeCCKrW_=sBZK-fMgCclT~ro zxLE!gp8z~Kzd;qycrY71kj2PXBp6+T7NL>YDC{5>jQ@@M5toQq(Hl{+_^o)5$8i|3# zQ#=@7hJ8To$S8nn12h`CBdCP+ydVFbo5abvJoXy9knO?ZY&x@+=?t`bmd>No=?C;3 zx|p`pq0CrjACTRPoyxuh@(<@Oan)Q5zk+|tI}2lk>%dFY3pxfBfl>Sid>$@@ZLm8M z0ah4)#0@y+a^Q#XMtCrc!*8Hzz^8UqNEE*FGkFnzmTL!|zKM-sGnuVSABLu%(wpcc znxIRmN7Qa=IyHhypnRzS%9&zGG3W_rDvAoDdQ($?EqR%GL1`!z-IZQKU#E?905grb z0{j+0>%dLs&Tx;pzq#w&%x2r3UBz~11K76gBKA4Uvje$fTm=`-ALb2wci{qP zLl0;Z^d0hpe}{L$#c&)l4|xt|=`-@6`}W# zv4|s*25*DI;ZM*~C=@aYFNNhov|!?&@GJR&ya#XQG~6@pD7T%P!%g5Oa-+HN+%#?# zcY?dY-Q;d_4V()f!4Kz`^0)Z{9uWeC7-5(&OIRqJ6mAH2gy+J2;gWC`tl`^*dBOl8 zUhoj4f{oAO|K_*xi}@*h7hn(BxjZf%)VCEpWezuzOXA`<2jC92usXJseZ$^kZ?UJ@ z{p>Dw8@rKR50G36-uJLOz}3g>XBOtXxGvmWZVy=1esaN})>Zsl;JghJCJBdyr$Vg| z0(F6gLd&64=qmIK%7e1O$Zv!=;Jx&NJHbN$=4;?%@KZPkxcLK+C}cF)!#5yTkr&8! zqzr*ke>4(}LSxW)vJ3H+=na1+2|EL;W~F&Uviy-)(aglMoA zXbn`)4diezGsbb<+2f!ePE%d@Fkn&SbE%AzZ6K76`r5B^&g^UYhENIY`s-XHJ)hqM zz2%lOKcV;hNm3(B<^AYw!tcyjp(D%lE1m(ngPKEcwIk*{K zMt|hnU@9iXI*QMvo|DPQOtw31)nR{=u@0=s%HG?B1LP;9Sw zkZca|R4NmHAhHzuiJgjcVjQv5DHFMk_fTI%XApYv9_%_U5ixKsbW~C+Xpz&11um46{AAA2MyA zX=}DVi>@;~FfX)+YxR~Zrs1X~FiNvidsov- zv$o-Lqr0_F)0wJF&9(~X~u zyG+~7ovf~8Ap2a{jYQ)k#l^CT3TMS##W+=-TJC^4d{UoKZBPzZe3vhg?UURS7XwY} zJGKZ(gmpp>VLq5W>-nu*2lg%Fz^-H`ft5RmUBNc6UR)b)F$lB_<9mbM#|db+dxdpE zk#L8f%FSmhnOW>=MouT%y)CDWkMzeIr)yH{&Q*DqpDMjy{Jh{@ZcNU=A7?YVW%T$S zn$hFOql~LRR;7FVn3%Ke$Kl*R^Y)gOHf*))B)x!(kaAw`TI9bs#Hnp&VqHQ|=K~$j zby(D)W4kx)BRjlqzqIYGmKQ@Nd7pB1a}ea`rFyiAzeGBiw;8%Lwr{+mL-hsvyLwN9 z+GsExw8@!6LN1~tc8Mjjo{CXQpdmSqce?B3>ZEhnudY{~RD6_omCcdxqEq;GbTG02 z8Ym?4H#r%Oq8^YRh!6D= zin%OS#ip>^84r4jy_@BeF<1Yraku7S9a*)q{CjClv8BMAyCG-ekF^;=8DZalrtkQ{ zX6S!h_`WsW`s2^^ep!>Ut`_XA8EvY>BV@3;%ArVo-FsT#{nj%&zf2sQ6q+FE7?a={ z?~+iFD0HlgAKSWT#0I|v_XejQswIlC#CE8ZJZxC4FVG%rbkVKU_HEQ@U+Ny}HyD~M zY1Ame4-FN$Nn}!!Tu|+GdgOY=t)IJ-TMOqEj?aNblP2FQg(NMBC}c3VfqqQAB4uQ* zeHYoD>|Nb%iC~5YV|Q_P$t5W)e*!dXQn_4xP1T^%sYWYfl$+$oCA7$hsgP>|!RC=m ztuG8W8^6|*RS(Ln#r+Dek@1ZJ`?&q z;I&tZ%Ls*|r~&>K{-AIca>P=^@$&T!j&4p~Uwky) z?YzCb_1>({EuUcT9v&@ROse5Bo2US@L9u*a#)A|rJxxBw)dr;@z$94i+RDg_>>@~t z-oQ>0Nz$>3=jzc;C!M35uQ^_J*x}IRkn8}d#>?u7ndl+N4uZCCNRMF8wU4B&YpE<^?PZ_F=UD++t_hcU| z`C5Ir(Q1H%wF+mqj$UWH-Th^O;bEPko!XLdx1;-poeezUH^L9~N%OeioF?B&yn@}h ze6qo^%S@R2SPCsKEjw)s$;bRy%tdllDRNxu8s*9P^$*LA>>K?o+BK$C%*>XWh+AR$ zpcB5k+?5U=B$dc4W{TC?^hNWzwx;q<*_yJ?6*=`n(@4vHdKHo(zOO8Fbo5LKI2E!e za#@sXL~8IF|E>P>{04hJaqXn+BkBr2Wq*+GO#AhN8se+J{JdP$H_!ctPe#!9ZQl=k zyZa^T+t=^EXSB&anmeKJVS!^oU_oeJWRWPxJ?nEupY+Yyf2QBgB1-I4@r}ub^W1*< z99P_{xA$?sy#Xsib6Y-XL&b&13=NwQNcdIz>b(m*Xy-V^9HJH6l?@_qS}@CeOE+sK zu+N^`Mo`6qOynb<=`h*Zq+di@%TKW*+8k>)F#cQX zlaZAn$Nk6oO!1iGxKef#UP;ff)fqhuUby(1;p47^BEwVG71lJS{{OyROa2xcO~z;`+x8Z+$Q3ZrFK0Ki5yH-y|}4AC+b1jY)>srn~x% zIz~6oSYe+C#SnzNi{oL}US7ZXEed)b`Y_xr>P=LSsGbqiT09Gx8c^z8=K4&%Ra%DW z1d?*Mb~e0jgc_G?=jhHGW?QXnGI~YQU$I%e%6X%^lkfb1p@G}{XZm#X`s%*QB}Bbe z7AV?|jDTLTFR5tTCu2!dg8pXXorViFuPc|A-zi0llL~IrU3W zY;*3IoK9aqfA05{`ugPK%a^v-!es}~dbrd7MRTW#fS_qE&G zro7ebsCL2Ky(T)omEXapu;Z-R#>sfx-AA0C<(Q0P6yt+(1y5`Z|ft?dOyYvbdF7YzpOFg;^DV$T)QBoiD! zz{@S%bB%Auz}LaOf>A${`+esO$E|9;Y%U%r^rlDK5-nARVEteECVjnOgt14{OYO%x zw02-kkLp+DYkmfnwlDmicOZ9mc45}x%Fj6C=lh>yKL@4NyxaQb?W=8Hf=iFo zwX&696I?b2zlq3fQ{OH%t|H!}Q)4G-{FIpEK{MUksuD%{P!&lVZQ2!eA8X_4poT-* zzD->%NmQNi0KX?2>(s`xm0xb4HB{T8Pm4!kIiUwal7m|LrFnjIIqC3DaYeKU_GW4= zYmK~dz1i6^&D>y_NPQK`C27uMz3=-tcw#`44)qHPUKsqwH_Umt{D$<1loxlz-f>sR ztCnTfxAsS1PaAJ)W4vM*Ygpans;|>rs@K;_YBH*dtG<+LiX8IC)_FvcZc6jeN*;I^-i7Dt1{Oz0qZ5(=wkKh7MqZv;3gP5S$=wx*Z^6KNQ@Co#5?{D#&?)$}au*(j0 z4v32Ri~WcoR02H*(akFAEqR>0ONLNw7%RsKv(Q_jV0oEhHSo{2Q$#B#tDdRGDCfxB zL;~_1ct1z-UD*J71liJFW_O{dvTfM+OfOc#*3z@6{Wg=az1~$bqpnX~>)L76Pb!j2 z-siK~mwwF3&d7fKBRKuUr;N8P-pqRQ{@v#^U13qZimnlh)yKSI!>+`ANqp3Caoo_> z%cACnEe!eKv&f+dG1$Hsa&>1L`)C?!=ht}E_HNkKG}QKmX%a4DE97RUN1j{!PWeCc z6Zy^Yd+7VZ`>aQImjd;1`EjXEypLFd4TJac1KA3?AI(z}X*uv+K4vrdxlkr@lF&<+ zD26NFDk|mIUYp@x6c7jch@rYIeB}Dv-m3U7;A-G;#;!@I*jf_ zw_v8TY20<*B&gvr$Q*35c#M1;u>Mvlj?4U|vn3v~8PY!_e-jq81R0FLNI#(myNQmW zQ|P|*MoLR|qyC}_sJ+xfsw+L3dBYrFF4L&}ky&T>*| zdosIzPyV*@^WC(tG|l^6ul9ayRrI=1jU=lI+}?U$@^ffao!FSvGpTF4X;I3+Jnurc zNwP?;i@9rKas3cYd(EbXOAVMS#l+b`^f5u_d|Mu+2nN=jwn%InGfkU&xqLW+){2f+sG6$b*v8`#CPY~%MzbsP5#23% zD;c8L>u}ArzxNOS-Tp7U-+9VCa94@TT*rCJ^Wrh+bU2I80oLGQFzy~vC+SzrCpH#% zUYUBqe98}bsx0-0ItB!Ysa8G0(rZUtZv}#LhjyFg_*?7RjkV(j4ksuD1n^oQ})t+Vk8v`HsF7@i>x!3ix z^G(M+${v#4NR}{&JIhRDCCq86fDEI{*f1dn>HtfT2dJDlCTbF$6D<+>N$k=@d8mA@ z7!Cr@z^{|R&Dmg+=%>6g{E9h0t@%AvhDi#uc`jLC*R#zd`$>mZVo(P5T*SOAHHdoIaqpRr? z>=ft`(jQGm9Z)H@1|LW$M5Bp9G#YsfN1!{1p5g?tRg{dEA_B0CCnIlA4QfQ^BNQ|q z>If}{73e~AKKeH@9PSK<0H5I-BnEh8U!WPtQ6vDqEGPvD-^Bi)Au`Q8sVP+lHU6cY zr^V{_R(}3DqByUR%KuQXvtUHQ)tq}jZe&(`dz%rRdFsdMEGqY2ZHVnKx>L2p<*;XG z_gDTc+FWa=Zxa#G#XrTPn`0j*C&$;KNBkgLT+>zE9zASmVQ@A)H5ZX{`5IgSEMtG= zCx>{~R8Kdb^WJ6d3tY0D#yCxMI_)q|Q7hVqc_L{b9`_g2T38GsZ3mc^Y$5kZcqB{~ zvUpFxFYz51NUhDcl*x!_WTuR)%y$-dw z+eX~Rw{@$isi9x}4L*~-V_ZtbHhv6gw>+~|+V$27^HfuXIgTPA6u&?i#J&nAhuJQ< z9%sA`dxW}bok+)t4u7ieD*`14h>z$fcrdg;=*53!*RWss%kUZW6eeIj@o>BbUqjp` ziirXE4eS6q8}0)Y@N2l!tc+g|je@(tvG7b-3+Bvy>#0KfXi`M~q`R>kh+}dTE5{6S@iR0JRWW@|{6@3)%NvfG`4bfN#K;kw4LA z=nxRSJB?4o2V+|FJ|Ll^&;)_ymk38-H#8Ml2bjPv@C>*Bwj)2#YVfW_dhqrk&n24>P#VKSe{b>r+Ht`g7QVIr6&`aHdqc|)HdJJ{vcI`crY z+{7AC{RGXrdR1*nP5Zh_RXLSy%XLLlix(9ambjGeE3PRyRX8?pRqk&^-gP0S5X4tW zI@h=jbu4g5@Yx&jIi_c@KbY;@L1+_}Dn2L8 z6pKN;tXwW~8Rq5fJ=kNY^HPT`4r3j90bRS391-`xy1;Wme8t9@0fpR;oyBeAG2n3= z4B~`~;mOEjBoQ5p-N&M_vuF@%g4Y5z_*v+0Sc%Ocl8C2hCpaGJ1XV-5kd0^n;HNe~ z@lac6A5;wDc+P;qd=qF5mCzxfkML304Pr@ZSPpN5s)av=4uCOypIgL#=cjR_Kr}nb z-p4*0XqUst^|n)Hg>j^zK)+o-T(58ZsM%Wksq$)NLse64xB3n>N#&1=ii?6vmi{a# zomMb8cS%l8(c79?`boBV^m~!WLx|`S|9jh&(W^od0%hU8(Wx;WVM^z8jANsjKiO`~ z5VFAf#7tXWk}a4Bz8^eV^hVjjHQB41cev+f_e78Gp4&ZFd5B$u)bY}}_yiDLISCRK zHbXB#Nne|f?Sx%IjimZhm#A|3Pc9c)j@Ds`M1N6*XtHPtQH)Q+{zTs*7vT~if_DT_ z>8p&IUBJpX1AiFGMW&!r!I+`oHE2&fkmyE);Ynyb@;fpUM3Q~b_sBuS0T~4D*bWZ> zQNqn|N5lsS0jtpjpm)sR+wl)UlI}+BoR6AXJ zPRnRY>mSzCR=HG7ukKXaui-=ery9IwYeiD!+Dg~*h>9IQpO#dW{#BKzUuYg|y-2T< zc)A+{I>9U|`{UW!f^W-^ONAKNl(p0&*S*}B9s z&$^ks&N%Zeg<9wad>`FLj2BN9cOxKt9Ek1*;-1)Rh~m0}Na$ehIhVn{WH!(X0oU#^ zm%win!qEn71YU~OBdxG5U|pLpZW5K?71%WNIr<%Q!WMxUS_Mnt8o>2PhGsw=g%v<6 z`inizE@Pb;4LyxsPr-CF{fsK7lBkPhG(D5aXV!6@0OMsFJ(BuHp0f|K?YEpVcGGuj zG=V5W7j2&AkA{79{&nN3Usj&1IP~)n2&bPeXq_j^K9D0SOs){spKMHNR5#6&X@ftt zYu9;4OiCE$e=?YE_aUKg{O*>4UZ<34(lps<#RaJh8Ojj0zNS!<%yiw9X0$j@{vGeb>e9u9f|<^`$)(l zxI)`NUc&`w0~Cs|=ymh~_6X~ZO~tIp0JJAohbCiVu}`;R3kUoIi*y8~8GwG2o@`(j$6ZJ|0s234)Jc0f%~bwqu;`Y{b{ z>*h6#hfe!+YBeX?>NCorN-g*$$DQehCB2M@bn*kFbJ^yUqUZ~_LFeRZr`FDP^#Vx@63mZc5xxonc7f21 zjVEw00S934QN?ONOxg5dzP^=5o{!v z#woe;>;{eoIFH~CavHuH)Cl_`(O@>4k(qc;kzJf99z~dN7Tbz1Axdx(i$mAL)4@D< zf!jl6ycooIT61BXJ9~_&r1#S==o@r2(+e;GMllF$XVu*A+y<~WU4f>-KJa5Gi;v+T z&=V`5EBrj>JbB%gXA8G(GCLVR>e4g=>TBx1YSOeTG^gtKG)!-FGh`dhCV%5LonGgn zzi;Sk-UXs$kF`?maqV2q2%~tMqn&VpSd_a9) z>WqgYqtF!5DzO274lScs*_HMH`VQNP8^V0FIa_vE-0a2lPwoTYwzS}OvX8iH&|+j4 z`T>24v_|g0OW|OIhF`$>P^vJKe+1Yau|brTEi0CD-LPE0b0~w6TLGS$m;j zU+vr4(i(Y#S&QoiG%@;_`s=!h`scS9kH=ds@=Q}gYTPp+*faQ)$7Ja$A)SpCCZS#!3_G%`0N*BzGSgY? zc4#_2TQXASDRC3QqP0?qy2=T5kvsXT!li}cR4JlNQ5PvLiN_$9IbZG!KMxuK6|)^k zSL+~CnBkSN&|G9qv< z-q#$dyI*H+_|i~P_pxz|KC)?vG0r%jyr#J2BlfdN_Lg*7P3Ypx;_E5%odN+tazE0G)2bl|H$Vjo1t(4(msat!UoOlR)#?#LueCH_P1 ztr(!76&Z>q<$cG^&aO@_j+pASR4o}UP7~b#ah4{2Hr;5qTV+-kn~P0tIcGf6G^y#6 z(bpof#@Zb0U+q(=GmM363C%<9ZL&ch9-gxxVgem zf#N%Xb%g=?x{fJhRx+hDPKN*%W*&8u8U;K!KJ*#-8*Qb1m?Xd$$^)4UXGQl2dJ#5`>+idP)y4>_w`$c!AN!>J7_g1UcR%um&DZkF@*p0@AiEtV%{t?7`x8*dX_ksK65$755(hvbixfsTNVsIFC& zsbO`oYMJV=VvEco9*6rNv!M?lpX3v{)c)2o$+QsI)QKh!Q+LA*Lmv}jNwp5M`%yV` zEXNBc;7&mIZ-+g^W)ZVR7excb-$Y|YNg^-;2qz+*V6iMT3Ehh5;A!w8XdYk@^$c{-L{C&o!hsB-W*B?=%dpU!qNEyxth7kJp5mRw@cz zj=C6?4d`5z!Z*9ciP%q3i-QpFMc&^c)bUHA=Xra&-f~*t(%_!r+C}Xu_rSDN7U|5t zXD^WB$P<>qCaw9DiM3SIejLK)u_U)h*pGA}+@v36w*W6xEA>}MRi~6kRbJ|2N=JE? zxQ@stUJ%*nDkw7`&UpiN6GeXJdA8ruQ;Oe&3e!A$|Sz$`cx zJ%N)%Iqce04Ftq0IZ@GKi2W}bQd^vGf zSrK<0^u#M}AJ_>#1K-pV{vf}A@6XTSQ~44;K!^p}&sUItNC^FeWq@@h6YTs?eh2v7 zlYh?j0NjW~#*e-Q5H2I@faOtP{mnYxdciu$*3Xt<$u$?6C)nnLQTW1^YAG>Ku^DX{ zc8#r#Ioh<%q&MYTY0GruScAH8Ok=d^p;=^2uzqMt(iQ7>TO!4oE+LMb^ceIGdFJ#k zC^{lNw3QF+bjPuScX9a0mQR9vd3;n3Q4DtO;<4T%!8t*C0(#AtBdc*|Y$LRf*>2xu z??i5;>e!{+b9xz-My+7OpcJGCyNS5~Ui59^wj@Q~4KQ@?057zwY>bSN4vv-u}c++6=aCwrs1PwX@}p<(8$3HP*V(ywU7uE;lJHR`Uu=k)_TQ zYkmZx$S15f%zez0&F##m%==8AO>IqI4Kc_*#i5ST(;^yut6e%fb#VuYo_@zY*En>O?84HB(bBgPFI?ao=n8TlwShUx zR5PoX8Kjtupo6(*0*3$eS{Eqpmx zf7XcnM4#{-fSLOWpO3G^I-n_tot-9YW2AZiO4Mvk=S*;?A9wz*cjWv`{q{KYceGTw5>{LG}b#8@s^18v`| za%-sRlquId%Jz($VcTG-HTj#?Tc(l&$VT%DlhW!Yu65n5oQpWnV=>w-#s5hF<=w@x zm9m3loo`z7_Q=g%5=WW3j|=VhAaJ<%@6I!1>v5XUC{k53#8zk<+n(x34`FYDNJT7* z*xOl1dnujIU5EBSTX_}V89I-ciA&M|$q#%KeoUm1e3rHWv!Nex3s~XB=qwCHHwz26 zY}Upgj6Z#slG6_-~;d&%o**9YzBD&uJ8${Mwlw>=6wK?72Fr@2lo!FL^A*{^)UAmu#`gi&S2H2 zz;E9CEPf|H4%|tBJ;Mj^R~c~4hyMXA+tXYQH-bL`=1FU?L-*$I@pt&S;O<>ut=q?C zfFl$1**(BT7PGMoNq?kA(11-h4dim0_F8hRy=^zp8pRs%USXK+FZQa^#q*(;mvcMW zXyUTCo9m>Ikf20YMy3&MSKjpa;N8jH$;l+uqBX=`#W9tS+=%ZIR3F{+{7yXUJqei3^?l1l>b`*8TTcLhH%S;9A&P3Q# zI0>Q*J=t5#9cBfa&6H5(p%E?VBOgXUb6w_`@u{Z%U$7eK_8`ZhrkY! z&J}UKVC=i|F1(y~=G*gO{7>#HK>G;SiDLn`w;x-_oB_KqM=zi?)M;uXVA4ZV7H*oeEUvmF*mQJ0mW) zoQ|lwD*lpPkfqA~nOniF2W<36u7;h+)-bm~ zPRL!59rBs3r+QI7RA-T9^W+ zKYM~b4`ek1c5oFtj0@tAfe6lApl@Aa8kyGYT~-WyKP}i2hGo98?ZJ!^^Roe?`!lzm zzbpKocFylLr#Oz|=j=J>`~7@K)|8p-32TMr>5-8p6gT6!5(Ac=+Cd@GI^B8oVw{{F^iRE4r z38hzF8mj&5@O4-s_KRBCNb_**0UN5~7H;Pb-p(VGrG8q$tN1>hpeDLN-PAy7ctV3n zRE)`|@`kLJTjc}UFE7el;!`*t#$igZh=XatB}~%o#Mwjz{GuMDetP{O|E~YdOL;Zk zGBo&(f~wDA5_hkbbJo{ddZ)Llw#Y--_{+R{@?z20>1$!G{Hdt literal 0 HcmV?d00001 diff --git a/dialogflow/resources/two_people.wav b/dialogflow/resources/two_people.wav new file mode 100644 index 0000000000000000000000000000000000000000..5114ebbd3105f06ceeb5a64536a0858f54b44097 GIT binary patch literal 31108 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 literal 0 HcmV?d00001 diff --git a/dialogflow/session_entity_type_management.py b/dialogflow/session_entity_type_management.py new file mode 100644 index 000000000000..2c8523253382 --- /dev/null +++ b/dialogflow/session_entity_type_management.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python + +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""DialogFlow API SessionEntityType Python sample showing how to manage +session entity types. + +Examples: + python session_entity_type_management.py -h + python session_entity_type_management.py --project-id PROJECT_ID list \ + --session-id SESSION_ID + python session_entity_type_management.py --project-id PROJECT_ID create \ + --session-id SESSION_ID \ + --entity-type-display-name room --entity-values C D E F + python session_entity_type_management.py --project-id PROJECT_ID delete \ + --session-id SESSION_ID \ + --entity-type-display-name room +""" + +import argparse + + +# [START dialogflow_list_session_entity_types] +def list_session_entity_types(project_id, session_id): + import dialogflow_v2 as dialogflow + session_entity_types_client = dialogflow.SessionEntityTypesClient() + + session_path = session_entity_types_client.session_path( + project_id, session_id) + + session_entity_types = ( + session_entity_types_client. + list_session_entity_types(session_path)) + + print('SessionEntityTypes for session {}:\n'.format(session_path)) + for session_entity_type in session_entity_types: + print('\tSessionEntityType name: {}'.format(session_entity_type.name)) + print('\tNumber of entities: {}\n'.format( + len(session_entity_type.entities))) +# [END dialogflow_list_session_entity_types] + + +# [START dialogflow_create_session_entity_type] +def create_session_entity_type(project_id, session_id, entity_values, + entity_type_display_name, entity_override_mode): + """Create a session entity type with the given display name.""" + import dialogflow_v2 as dialogflow + session_entity_types_client = dialogflow.SessionEntityTypesClient() + + session_path = session_entity_types_client.session_path( + project_id, session_id) + session_entity_type_name = ( + session_entity_types_client.session_entity_type_path( + project_id, session_id, entity_type_display_name)) + + # Here we use the entity value as the only synonym. + entities = [ + dialogflow.types.EntityType.Entity(value=value, synonyms=[value]) + for value in entity_values] + session_entity_type = dialogflow.types.SessionEntityType( + name=session_entity_type_name, + entity_override_mode=entity_override_mode, + entities=entities) + + response = session_entity_types_client.create_session_entity_type( + session_path, session_entity_type) + + print('SessionEntityType created: \n\n{}'.format(response)) +# [END dialogflow_create_session_entity_type] + + +# [START dialogflow_delete_session_entity_type] +def delete_session_entity_type(project_id, session_id, + entity_type_display_name): + """Delete session entity type with the given entity type display name.""" + import dialogflow_v2 as dialogflow + session_entity_types_client = dialogflow.SessionEntityTypesClient() + + session_entity_type_name = ( + session_entity_types_client.session_entity_type_path( + project_id, session_id, entity_type_display_name)) + + session_entity_types_client.delete_session_entity_type( + session_entity_type_name) +# [END dialogflow_delete_session_entity_type] + + +if __name__ == '__main__': + import dialogflow_v2 + parser = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawDescriptionHelpFormatter) + parser.add_argument( + '--project-id', + help='Project/agent id. Required.', + required=True) + + subparsers = parser.add_subparsers(dest='command') + + list_parser = subparsers.add_parser( + 'list', help=list_session_entity_types.__doc__) + list_parser.add_argument( + '--session-id', + required=True) + + create_parser = subparsers.add_parser( + 'create', help=create_session_entity_type.__doc__) + create_parser.add_argument( + '--session-id', + required=True) + create_parser.add_argument( + '--entity-type-display-name', + help='The DISPLAY NAME of the entity type to be overridden ' + 'in the session.', + required=True) + create_parser.add_argument( + '--entity-values', + nargs='*', + help='The entity values of the session entity type.', + required=True) + create_parser.add_argument( + '--entity-override-mode', + help='ENTITY_OVERRIDE_MODE_OVERRIDE (default) or ' + 'ENTITY_OVERRIDE_MODE_SUPPLEMENT', + default=(dialogflow_v2.enums.SessionEntityType.EntityOverrideMode. + ENTITY_OVERRIDE_MODE_OVERRIDE)) + + delete_parser = subparsers.add_parser( + 'delete', help=delete_session_entity_type.__doc__) + delete_parser.add_argument( + '--session-id', + required=True) + delete_parser.add_argument( + '--entity-type-display-name', + help='The DISPLAY NAME of the entity type.', + required=True) + + args = parser.parse_args() + + if args.command == 'list': + list_session_entity_types(args.project_id, args.session_id) + elif args.command == 'create': + create_session_entity_type( + args.project_id, args.session_id, args.entity_values, + args.entity_type_display_name, args.entity_override_mode) + elif args.command == 'delete': + delete_session_entity_type( + args.project_id, args.session_id, args.entity_type_display_name) diff --git a/dialogflow/session_entity_type_management_test.py b/dialogflow/session_entity_type_management_test.py new file mode 100644 index 000000000000..5931ea2ea81a --- /dev/null +++ b/dialogflow/session_entity_type_management_test.py @@ -0,0 +1,63 @@ +# Copyright 2017 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +import os + +import entity_type_management +import session_entity_type_management + +PROJECT_ID = os.getenv('GCLOUD_PROJECT') +SESSION_ID = 'fake_session_for_testing' +ENTITY_TYPE_DISPLAY_NAME = 'fake_display_name_for_testing' +ENTITY_VALUES = ['fake_entity_value_1', 'fake_entity_value_2'] + + +def test_create_session_entity_type(capsys): + # Create an entity type + entity_type_management.create_entity_type( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME, 'KIND_MAP') + + session_entity_type_management.create_session_entity_type( + PROJECT_ID, SESSION_ID, ENTITY_VALUES, ENTITY_TYPE_DISPLAY_NAME, + 'ENTITY_OVERRIDE_MODE_SUPPLEMENT') + session_entity_type_management.list_session_entity_types( + PROJECT_ID, SESSION_ID) + + out, _ = capsys.readouterr() + + assert SESSION_ID in out + assert ENTITY_TYPE_DISPLAY_NAME in out + for entity_value in ENTITY_VALUES: + assert entity_value in out + + +def test_delete_session_entity_type(capsys): + session_entity_type_management.delete_session_entity_type( + PROJECT_ID, SESSION_ID, ENTITY_TYPE_DISPLAY_NAME) + session_entity_type_management.list_session_entity_types( + PROJECT_ID, SESSION_ID) + + out, _ = capsys.readouterr() + assert ENTITY_TYPE_DISPLAY_NAME not in out + for entity_value in ENTITY_VALUES: + assert entity_value not in out + + # Clean up entity type + entity_type_ids = entity_type_management._get_entity_type_ids( + PROJECT_ID, ENTITY_TYPE_DISPLAY_NAME) + for entity_type_id in entity_type_ids: + entity_type_management.delete_entity_type( + PROJECT_ID, entity_type_id)