langchain/cookbook/langgraph_agentic_rag.ipynb

486 lines
92 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"id": "625868e8-46cb-4232-99de-e95aee53c3a3",
"metadata": {},
"outputs": [],
"source": [
"! pip install langchain-chroma langchain_community tiktoken langchain-openai langchainhub langchain langgraph"
]
},
{
"cell_type": "markdown",
"id": "425fb020-e864-40ce-a31f-8da40c73d14b",
"metadata": {},
"source": [
"# LangGraph Retrieval Agent\n",
"\n",
"We can implement [Retrieval Agents](https://python.langchain.com/docs/use_cases/question_answering/conversational_retrieval_agents) in [LangGraph](https://python.langchain.com/docs/langgraph).\n",
"\n",
"## Retriever"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "e50c9efe-4abe-42fa-b35a-05eeeede9ec6",
"metadata": {},
"outputs": [],
"source": [
"from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
"from langchain_chroma import Chroma\n",
"from langchain_community.document_loaders import WebBaseLoader\n",
"from langchain_openai import OpenAIEmbeddings\n",
"\n",
"urls = [\n",
" \"https://lilianweng.github.io/posts/2023-06-23-agent/\",\n",
" \"https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/\",\n",
" \"https://lilianweng.github.io/posts/2023-10-25-adv-attack-llm/\",\n",
"]\n",
"\n",
"docs = [WebBaseLoader(url).load() for url in urls]\n",
"docs_list = [item for sublist in docs for item in sublist]\n",
"\n",
"text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n",
" chunk_size=100, chunk_overlap=50\n",
")\n",
"doc_splits = text_splitter.split_documents(docs_list)\n",
"\n",
"# Add to vectorDB\n",
"vectorstore = Chroma.from_documents(\n",
" documents=doc_splits,\n",
" collection_name=\"rag-chroma\",\n",
" embedding=OpenAIEmbeddings(),\n",
")\n",
"retriever = vectorstore.as_retriever()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "0b97bdd8-d7e3-444d-ac96-5ef4725f9048",
"metadata": {},
"outputs": [],
"source": [
"from langchain.tools.retriever import create_retriever_tool\n",
"\n",
"tool = create_retriever_tool(\n",
" retriever,\n",
" \"retrieve_blog_posts\",\n",
" \"Search and return information about Lilian Weng blog posts.\",\n",
")\n",
"\n",
"tools = [tool]\n",
"\n",
"from langgraph.prebuilt import ToolExecutor\n",
"\n",
"tool_executor = ToolExecutor(tools)"
]
},
{
"cell_type": "markdown",
"id": "fe6e8f78-1ef7-42ad-b2bf-835ed5850553",
"metadata": {},
"source": [
"## Agent state\n",
" \n",
"We will defined a graph.\n",
"\n",
"A `state` object that it passes around to each node.\n",
"\n",
"Our state will be a list of `messages`.\n",
"\n",
"Each node in our graph will append to it."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "0e378706-47d5-425a-8ba0-57b9acffbd0c",
"metadata": {},
"outputs": [],
"source": [
"import operator\n",
"from typing import Annotated, Sequence, TypedDict\n",
"\n",
"from langchain_core.messages import BaseMessage\n",
"\n",
"\n",
"class AgentState(TypedDict):\n",
" messages: Annotated[Sequence[BaseMessage], operator.add]"
]
},
{
"attachments": {
"f886806c-0aec-4c2a-8027-67339530cb60.png": {
"image/png": "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eGlmOlBpeGVsWERpbWVuc2lvbj45NDU8L2V4aWY6UGl4ZWxYRGltZW5zaW9uPgogICAgICAgICA8ZXhpZjpVc2VyQ29tbWVudD5TY3JlZW5zaG90PC9leGlmOlVzZXJDb21tZW50PgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KWU789QAAQABJREFUeAHsnQm8VdP7h18qlVIaiEoDmSqzQqaUKcoQypjMM5kjfiQZEikl/xASMmesRCKSocxlTKXB3ExR3f9+Vtax77nnnqlz7z3nnu/7+Zyzp7XXXvvZa++13vW+a631CgIxiQiIgAiIgAiIgAiIgAiIgAiIgAjkAIH1cyCNSqIIiIAIiIAIiIAIiIAIiIAIiIAIOAJSYpURREAEREAEREAEREAEREAEREAEcoaAlNiceVRKqAiIgAiIgAiIgAiIgAiIgAiIgJRY5QEREAEREAEREAEREAEREAEREIGcISAlNmcelRIqAiIgAiIgAiIgAiIgAiIgAiIgJVZ5QAREQAREQAREQAREQAREQAREIGcISInNmUelhIqACIiACIiACIiACIiACIiACEiJVR4QAREQAREQAREQAREQAREQARHIGQJSYnPmUSmhIiACIiACIiACIiACIiACIiACUmKVB0RABERABERABERABERABERABHKGgJTYnHlUSqgIiIAIiIAIiIAIiIAIiIAIiICUWOUBERABERABERABERABERABERCBnCEgJTZnHpUSKgIiIAIiIAIiIAIiIAIiIAIiICVWeUAEREAEREAEREAEREAEREAERCBnCEiJzZlHpYSKgAiIgAiIgAiIgAiIgAiIgAhIiVUeEAEREAEREAEREAEREAEREAERyBkCUmJz5lEpoSIgAiIgAiIgAiIgAiIgAiIgAlJilQdEQAREQAREQAREQAREQAREQARyhoCU2Jx5VEqoCIiACIiACIiACIiACIiACIiAlFjlAREQAREQAREQAREQAREQAREQgZwhICU2Zx6VEioCIiACIiACIiACIiACIiACIiAlVnlABERABERABERABERABERABEQgZwhIic2ZR6WEioAIiIAIiIAIiIAIiIAIiIAISIlVHhABERABERABERABERABERABEcgZAlJic+ZRKaEiIAIiIAIiIAIiIAIiIAIiIAJSYpUHREAEREAEREAEREAEREAEREAEcoaAlNiceVRKqAiIgAiIgAiIgAiIgAiIgAiIgJRY5QEREAEREAEREAEREAEREAEREIGcISAlNmcelRIqAiIgAiIgAiIgAiIgAiIgAiIgJVZ5QAREQAREQAREQAREQAREQAREIGcISInNmUelhIqACIiACIiACIiACIiACIiACEiJVR4QAREQAREQAREQAREQAREQARHIGQJSYnPmUSmhIiACIiACIiACIiACIiACIiACUmKVB0RABERABERABERABERABERABHKGgJTYnHlUSqgIiIAIiIAIiIAIiIAIiIAIiICUWOUBERABERABERABERABERABERCBnCEgJTZnHpUSKgIiIAIiIAIiIAIiIAIiIAIiICVWeUAEREAEREAEREAEREAEREAERCBnCEiJzZlHpYSKgAiIgAiIgAiIgAiIgAiIgAhIiVUeEAEREAEREAEREAEREAEREAERyBkCUmJz5lEpoSIgAiIgAiIgAiIgAiIgAiIgAlJilQdEQAREQAREQAREQAREQAREQARyhoCU2Jx5VEqoCIiACIiACIiACIiACIiACIiAlFjlAREQAREQAREQAREQAREQAREQgZwhICU2Zx6VEioCIiACIiACIiACIiACIiACIiAlVnlABERABERABERABERABERABEQgZwhIic2ZR6WEioAIiIAIiIAIiIAIiIAIiIAISIlVHhABERABERABERABERABERABEcgZAlJic+ZRKaEiIAIiIAIiIAIiIAIiIAIiIAJSYpUHREAEREAEREAEREAEREAEREAEcoaAlNiceVRKqAiIgAiIgAiIgAiIgAiIgAiIgJRY5QEREAEREAEREAEREAEREAEREIGcISAlNmcelRIqAiIgAiIgAiIgAiIgAiIgAiIgJVZ5QAREQAREQAREQAREQAREQAREIGcISInNmUelhIqACIiACIiACIiACIiACIiACEiJVR4QAREQAREQAREQAREQAREQARHIGQJSYnPmUSmhIiACIiACIiACIiACIiACIiACUmKVB0RABERABERABERABERABERABHKGgJTYnHlUSqgIiIAIiIAIiIAIiIAIiIAIiICUWOUBERABERABERABERABERABERCBnCEgJTZnHpUSKgIiUJIECgoKSjJ6xS0C5ZKA3pty+Vh1UyIgAiKQ9QSkxMZ4RKtWrbIvvvjC/f74448YIbRLBFIn8Pfff9t7771nU6ZMsd9//71QBI8++qgdeOCB9vHHHxfaXxIb8+fPd9fiev63ePHipC713XffuXOGDBmSVHgfaNasWZF3infr+++/txUrVvjDZb6cMGGCtWjRwgYPHlzmaVECRCAdArzXvFszZsxI5/SUz0F5PeGEE2yvvfayX375JeXzdYIIFEeAOhhlxPjx412ZuHTp0kjQ0iwrueh9993nyryvv/46koZ0Vv78889CZeCXX35pv/76q6XTCHTyySdHym7K8MmTJ6eTJJ0jAjlPoGLO30EJ3ACKxLHHHutiPuuss+y6664rgaukFuVpp51mn376qX3wwQdWsaIeW2r0yjb08uXL7ZprrrEXXnihUELOP/98u/TSS22DDTZwSu23335rhC1pqVSpkm2zzTbuMhMnTnTXpNKQjKB4ks6ff/45meCRMLxDkyZNimz7lQsvvNAuv/xyW3/91NrTMv0+fP75544DDQykSSICuUaA98hXZqdNm2Z16tRJ+Rb++usv23vvvW3PPfe0e++9N+75VMr99X788UfbdNNN44bXQRFIhgB5im9wdEPvHXfcYV26dCnVspL00kBDmbeuja40LnXu3LkIgu23397uvPNO14ha5GAxOxo3bmw1atSwb775xqUtrOQXc4p2i0C5JCBtKMZjfeutt9xeKgHjxo3LCiWWD3r0Rz1G0rUrCwn83//9n1NgqRjSgopFFovf888/b926dbPNN9+8VFO9ySabRCqoKINYIUtL+vbt6y5F4fvMM884DhTIVE5SkUy/D2eeeaY1bdrUWrdunUoyFFYEsoIAlVgq/5RZvBvvvvuuHXHEESmnbc2aNe78ZMqaatWq2UsvvWR4K+26664pX0sniEA0gQ8//NBZ99lPI2+rVq0ML57evXsbDa7HHXdc9Ck5t33wwQfb/vvvbzQYjR071j766CM744wz7O2333YN2snckC9H77//frv55puTOUVhRKBcEpASG+Ox8mHZcsst7cgjj7QBAwbYDz/84Cq44aC0qr3zzjvOgnTAAQcY7pi01nXq1MmqVq0aCUrFAgsqlYOddtrJ9tlnn8gxrFkozLvvvrstXLjQuZluu+221rZt24i19ZVXXnEWIu+u9dRTT0WO0fJN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IkkhPr3vRbBoR5IEUvkuJYoymfc22XKMaylvJyJePo+nkidVViauOyaTS1RWqm6cTD4pL2GkxIaeJG6XX3zxhVMGcHXJZmF+UNwnGSHV97fN5vSWx7TlUn4pj/xz4Z5oI6RSgSvxkCFD7Ntvv3X9e+lbn4rofU+FVn6HzbXvkvJ2+c+vuZYny/8Tyb47VFmZfc8kF1IkJTYXnpLSKAIikHMEwt4SPvH0h6f/fSwLsg+jpQiIgAiIgAjkCwGVlfnypDN/n3k/sFPmkSpGERABETA3MBaty7gYMwoloywzcJZEBERABERABERgLQEGkVRZqdyQDgFZYtOhpnNEQAREQAREQAREQAREQAREQATKhEDezxNbJtR1UREQAREQAREQAREQAREQAREQgbQISIlNC5tOEgEREAEREAEREAEREAEREAERKAsCUmLLgrquKQIiIAIiIAIiIAIiIAIiIAIikBYBKbFpYdNJIiACIiACIiACIiACIiACIiACZUFASmxZUNc1RUAEREAEREAEREAEREAEREAE0iIgJTYtbDpJBERABERABERABERABERABESgLAhIiS0L6rqmCIiACIiACIiACIiACIiACIhAWgSkxKaFTSeJgAiIgAiIgAiIgAiIgAiIgAiUBQEpsWVBXdcUAREQAREQAREQAREQAREQARFIi4CU2LSw6SQREAEREAEREAEREAEREAEREIGyICAltiyo65oiIAIiIAIiIAIiIAIiIAIiIAJpEZASmxY2nSQCIiACIiACIiACIiACIiACIlAWBKTElgV1XVMEREAEREAEREAEREAEREAERCAtAlJi08Kmk0RABERABERABERABERABERABMqCgJTYsqCua4qACIiACIiACIiACIiACIiACKRFQEpsWth0kgiIgAiIgAiIgAiIgAiIgAiIQFkQkBJbFtR1TREQAREQAREQAREQAREQAREQgbQISIlNC5tOEgEREAEREAEREAEREAEREAERKAsCUmLLgrquKQIiIAIiIAIiIAIiIAIiIAIikBYBKbFpYdNJIiACIiACIiACIiACIiACIiACZUFASmxZUNc1RUAEREAEREAEREAEREAEREAE0iIgJTYtbDpJBERABERABERABERABERABESgLAhIiS0L6rqmCIiACIiACIiACIiACIiACIhAWgSkxKaFTSeJgAiIgAiIgAiIgAiIgAiIgAiUBQEpsWVBXdcUAREQAREQAREQAREQAREQARFIi4CU2LSw6SQREAEREAEREAEREAEREAEREIGyICAltiyo65oiIAIiIAIiIAIiIAIiIAIiIAJpEZASmxY2nSQCIiACIiACIiACIiACIiACsQl888039sUXX9iaNWuKBJg1a5Y7tmLFiiLHtCM5AlJik+OkUCIgAiIgAiIgAiIgAiIgAiKQFIFHH33UDj/8cBs/fnyh8EuWLLHDDjvMunXrVmi/NlIjICU2NV4KLQIiIAIiIAIiIAIiIAIiIAJxCZx//vnu+KBBg6ygoCASFuV2+fLldtVVV1mVKlUi+7WSGoH1Aqj/UU3tXIUWAREQAREQAREQAREQAREQARGIQeDmm2+2+++/3x566CFr166dU15btWplderUsQkTJlilSpUiZ02ePNk+/fRT536800472T777BM55le+/PJLmzp1qi1cuNBWrlxpNWvWdOFatGjhg+TNsmLe3KluVAREQAREQAREQAREQAREQARKicC5557rlNi7777bKbGPP/64U2T79u1bSIG9/PLL7ZlnnimUqi5dutgdd9zh9mFzvPbaa43zo2XAgAGWj0qsLLHROUHbIiACIiACIiACIiACIiACIpABAnfeeafhUoxFtkePHlavXj3XT7ZixbW2xDfeeMNOP/10w/p6xRVXGPv79etnH3/8sVNssdzOnDnTDjjgAKtWrZrdc8891rRpU2eF/euvv2zjjTe26tWrZyCluRWF+sTm1vNSakVABERABERABERABERABHKEwBlnnOGUz7POOivSF9YrsNwCbsVIr169bL/99rM2bdrYRRdd5PZNmzbNLTfccEO3pA/tP//8Y7Vr13YuyQ0bNsxLBRYYcid2WUJ/IiACIiACIiACIiACIiACIpBZAlhKGeQJ1+Dtt9/eDjnkkEIX+PHHH932DTfcENnPwE/IL7/84pabbbaZnXfeeTZ06FA755xz3L6WLVsainGnTp2sQoUKbl8+/UmJzaenrXsVAREQAREQAREQAREQAREoVQLt27d3SmyHDh1s/fULO8IyOBPSqFEjQ1kNC67EXnr27GmnnHKKvf3228YgUC+++KJdcsklzhJ74IEH+mB5s5QSmzePWjcqAiIgAiIgAiIgAiIgAiKQTQS22247p5DS3/Wmm26Km7QGDRrYCSec4H4HHXSQczseO3asSYmNi00HRUAEREAEREAEREAEREAEREAEMkXg5JNPtgcffNCee+45++ijjwyrLVPwzJs3z3r37m2VK1e27777zgYOHGgosfSL5RgDQiFbb711ppKSU/HIEptTj0uJFQEREAEREAEREAEREAERKC8EcCd+/vnnjTllX3vtNTenrL83puhp0qSJzZkzx1lr/X6WWG67d+9uDByVj6IpdvLxqeueRUAEREAEREAEREAEREAEsorA6tWr7bfffjOWWGOxwnr5888/bdGiRcacsSiwNWrUKNK/1ofNh6WU2Hx4yrpHERABERABERABERABERABESgnBAoPj1VObkq3IQIiIAIiIAIiIAIiIAIiIAIiUD4JSIktn89VdyUCIiACIiACIiACIiACIiAC5ZKAlNhy+Vh1UyIgAiIgAiIgAiIgAiKQOwRuueUW22OPPXInwUppmRLQ6MRlil8XFwEREAEREAEREAEREIH8JLBgwQIbPny4jRgxwlasWGEVKlTITxC665QJSIlNGZlOEAEREAEREAEREAEREAERSJfAhx9+aE8++aQ9/fTTVrFiRVu1apWL6vbbb083Sp2XZwQ0OnGePXDdrgiIgAiIgAiIgAiIgAiUBYE33njDKa5jxoyx+vXrW+fOnW3w4MG27bbb2rJly2zy5MllkSxdMwcJyBKbgw9NSRYBERABERABERABERCBXCEwZcoUe+SRR+zVV1+1Vq1a2c0332xHHXWUtWzZ0nbYYQf7/PPPTVbYXHma2ZFOWWKz4zkoFSIgAiIgAiIgAiIgAiJQrgiMHz/eBg4c6JTUI4880imu7dq1c/fYuHFj23PPPW2TTTax9957z6ZOnVqu7l03U7IENDpxyfJV7CIgAiIgAiIgAiIgAiKQVwRGjhxprVu3tjPPPNOOPfZYe+utt2zQoEHmFdiOHTvaXnvtZRdccIG99NJLdvHFF+cVn3g3u2TJErv77rvjBdGxgIDciZUNREAEREAEREAEREAEREAE1pnAxIkTrVevXrZmzRo7//zzrXv37kXixAKLAjtq1Cg7++yzbaONNnKKbpGAebpj+vTpNmDAAHf3PXr0yFMKiW9bSmxiRgohAiIgAiIgAiIgAiIgAiKQgMDHH3/sFNJLL700ZsiwAvvmm2/auHHj7LLLLrNq1arFDJ+POwsKCvLxtlO+ZymxKSPTCSIgAiIgAiIgAiIgAiIgAtEEilNeCRdWYNlGga1UqZIdc8wxbEqiCKy33npRe7QZJqA+sWEaWhcBERABERABERABERABEcgoARTYXXbZxbkQE/Eff/xhL774op100knWsGHDjF4r1yOTJTa5JyglNjlOCiUCIiACIiACIiACIiACIpAigW222ca22morGz16dORMrLDLly9XX9gIkaIrssQWZRLeIyU2TEPrIiACIiACIiACIiACIiACGSGA9bVmzZo2YcKEQvGh0J544olujthCB7RhssQmlwmkxCbHSaFEQAREQAREQAREQAREQASSJNCmTRtbsWKFffjhh4XOmDFjhk2ZMsUpsYUOaKMQAVliC+EosqGBnYog0Q4REAEREAEREAEREAEREIF0CRx44IE2b948mz17dpEonn32WevataussEXIrN0hS2wxYKJ2yxIbBUSbIiACIiACIiACIiACIiAC6RE48sgj7dtvv7Wvv/46ZgSPP/64HX300TGPaed/BGSJ/Y9FrDUpsbGoaJ8IiIAIiIAIiIAIiIAIiEBKBI4//nj75JNPbNq0aValSpUi5/7yyy92yCGH2F577VXkmHasJeAtsX4pLrEJSImNzUV7RUAEREAEREAEREAEREAEkiSAAvvee+/ZpEmTrE6dOjHP2nTTTW3AgAExj2lnYQKyxBbmEb0lJTaaiLZFQAREQAREQAREQAREQASSJuAV2DFjxlijRo2SPk8BixKQBbYok1h7pMTGoqJ9IiACIiACIiACIiACIiACCQl4BZYBm5o3b54wvAIkR0CW2PicpMTG56OjIiACIiACIiACIiACIiACMQh4Bfbhhx+23XffPUYI7UqVgCyxyRHTFDvJcVIoERABERABERABERABERCBfwkwwjADOA0aNMgOOOCAUuWyevVqW3/99S1srVyzZo3bDu8r1URl+GLl5T4yjCUSnSyxERRaEQEREAEREAEREAEREIHyS2D69Ol2991325IlS9bpJtu1a+cU2D59+hhT6pS2nHvuuXbJJZdELrt06VJr2bKlvfTSS5F9uboiS2xyT05KbHKcFEoEREAEREAEREAEREAEcpIASuvZZ55pHTp0cKMD792mjaHQpiO77rqrff/993bllVdat27d0olinc/p0aOHvfDCCzZz5kwX18iRI61evXp22GGHReJesWKFrVq1KrLtV1ASUXqZ7uevv/7yu7NuKUts/EciJTY+Hx0VAREQAREQAREQAREQgZwlMG7cONtn771tdaC4XXPaada6RXNbEqx37dIlZUV2yy23tN9//91OP/10u/DCC8uMSYsWLaxjx442dOhQW758ud1zzz129dVXW8WKFd32LbfcYijbrVu3tmHDhkXS+c4777g5arHatmrVyvYOuGSrSImN/2TUJzY+Hx0VAREQAREQAREQAREQgZwjgPX18ksvdXO3Xhsor50PaOvuoXvHw+25Nyda3+HD7azAOjtm7FirUaNGwvtr3LixC4P78A033JAwfEkHuDS4t/bt21vlypWtadOmdvDBB7tLTpgwwV588UV7/PHHbdGiRXbqqada586drW7dutavXz8XdtSoUVarVq2YltqSTnei+OVOnIjQ2uOyxCbHSaFEQAREQAREQAREQAREICcIoMB2OfZYW7hggb1wZ/+IAusTj0L75n1DbdsG9a3DoYcmtMh6BRbLJQM5ZYM0a9bMjjvuOHv00UedazMDPSHjx4830vvZZ5/ZnDlzrFq1ajZp0iR3rE3gRj158mTDUouiu8EGG7j92fgnS2z8pyIlNj4fHRUBERABERCBvCewusBs7uLV9v7MpXbnyzPt1IFTrc9zM23Qq9/b9Y9Pt+9/Wp73jARABLKFAAps10C5W7Nypd179VXWYJNNYiatRqDc3Ru44LbaZmvnWozbcSzxCuwhhxzirJuxwpTVviOOOMJdum3btpEkLF682ObPn29z5851v5NPPtm22GILdxyX46eeesq22WYb52aMEpxtIktsck9E7sTJcVIoERABERABEcgrAstWrLYRE2fbrJ+X29dzl9pPv64dAKVy5Yq2cc2q9voHc23Fin8ck9c+WGC7Na9r3Q9oZK23rpVXnHSzIpBNBLwCuyjot4oFFkU1kdwW9G3ted99dvbZZ1v//v2dddOfc/7557vVrl27Oldcvz9blhUqVHCW1nB69tlnH5s4caLtvPPOrt8rAzw1aNDABWEgqCZNmjilFmVx8ODBbpCnjTbaKBxFVqzLEhv/MUiJjc9HR0VABERABEQg7wiM/fgne2DcLPvxXwtrlSqVrOX2m9t2TerY1o3rRHgsW/63/bFkhX3x3c/26dc/2UXTf7P2rTZ3x6/pvI1tVFXVjAgsrYhACRNAgT0+GKwJF9qRfW5KSoH1SbotmLKm4eab2xVXXOF2YaF877337I8//jDmg6UvaTZKLEWve/fuLqm4Pc+YMcOtcy/169d3CjoDU3np2bOnZZsCK0usfzrxl+sFoAInIYkIiIAIiIAIiIAImD3z3jy748mvHIomjWrbtk3q2nZb1rUNA0U2nvy28C/75OsF9kWgzCKb1q5qN52wnW3XMPssHPHuQ8dEIBcJOAtsYC39cfZse/Sm3rZ9YG1MR0ZPm2Z97xlsTz75pDVv3tymTJlie+65ZzpRZcU5DOzEwE9Vq1Z16WHKHdyNGcW4evXqhiU32+SNN95woz9fd911dtZZZ2Vb8rImPWoizZpHoYSIgAiIgAiIQNkSGDFxjg0Z/a01DaytuwaW120Cy2uyUrdWVTtwzy1tj5Zr3fbGTf7ezh08za4/cXtrv+OmyUajcOtIACscU44gVN6ZEiXfZGXQF9TPH8q9Y4GrWbNmucUQUWCDZ78uCiyAjgqmpVnvsssM9+H7778/pxVY7mfjjTdmERGU1zp1kv+uRU4sxRXZF5ODrYGdkuOkUCIgAiIgAiJQrgncN26mU2B3DpTQ4zu0TEmBDYPZqHpl43fswc2tYf1adufo78KHtV7CBLDeHBqMNsuPPo6x5NNPP7VXX3011qFysW92YI30DFi+9tpr5eK+Yt2EV2ALVq+2R3vfmLYFNhz3kbvuYpdccIGzAk6fPj18SOsikDUEpMRmzaNQQkRABESgfBFQa3LuPM+v5y2zh8b8YNtstal12KdZxhKOIlt74+p26cO5WRHGre/coK8grpXffvttxriUdES9evUyFLnXX3895qWYbuTBBx+MeSwbd/bp0yelUXEZeZb757d50M+zvEpEgQ16Bj564w0ZUWAdq3/+sVP23ccObNfOWWQZ5VdSegRUdibHWkpscpwUSgREQASykgD9e77//ns3L97HH3/sRlnMhoTefffd1qJFC3v77bezITlZl4YbbrjBmG9xwIABbvCUsk7gsPGzrVHDWnZQ4A6cadl7l0Y2+ZMFdverP2Q66hKPj/5ya9assZtvvtkOPPBAO/74492clAx2k4uCmzHfjFjy119/uXuNdezvv/82jnuhkr06sPx5Yd1XvP36smXL3GG/9GFZendnvy8c39KlS/1utyS+r7/+2k2Vwjq/sHAu5/zyyy+F0hgOUx7XIwpskD9H9u1rG2V4vtOC4HnfdvZZdtB++9lZZ55pXE9SugRiDVpVuinI7qtJic3u56PUiYAIiECxBJiwvXXr1tYuaC0/M6hkHHXUUdayZUs3B16xJ63DgaFDh9quQX8plOVE8u6777qK6hdffJEoaF4e7927t10W9Dv74IMPnGJ00EEHGYp/WVj7Pp65yN755CdrvtUmVmOjyhl/HptvUt123aGhvfbRAvtn9ZqMx1+SETL35LBhwwyL7O233+4UQNx1UWivv/56mzp1aklePqNxX3PNNW6gnq222qpQulEysXRut9121r59e3v66acj112wYIH973//c1OVcPyMM85wiuLIkSMdAx8QTqNGjXKbO+ywg+0XKD40YjE/J8tXXnnFHfvhhx/s4osvduk4/PDD3TQoHHjppZdcfPTD5BvGEsUUt2f69GI5HjJkiFtn+6kqJ88AAEAASURBVPPPP3fxvfPOO7bXXnu5c1q1auUahtyBcv6HZZRRiKuvZzbi2musekHJvFcosrec1t223ayem3dWimzpZCzfIFQ6V8vdq0iJzd1np5SLgAjkMYEPP/zQTjjhBGOqAObxe+ihhwzrHsL8eCVRCFKp5HpYZRLJwIED3fx7fqqDROHz8fgxxxxjTzzxhD3yyCO2xx57OJdVlCOep6/0lwaXFz76xerUrmYtty65wZf22rGhLV32t42YtKA0binj19h0001dY8MzzzxjNOYw/+SIESOsc+fOrt/puHHjMn7NTEY4f/58545777332tixYyPTjnANFHTyIUoo06owxYq3npI3aSxjOXr0aPsncDP99ddfE35f4LLLLrs45XL33Xe3acGItwguzHxHuCZ9VbFwI3yvGIjpkEMOcelDSeU7hgKMIktjHQ11rPPbfvvt3XlM+9K0aVN766237LPPPnMeKe5AOf7zFtiFwbd4yNVXpzSNTrpYmEd22wb1rWugOEuRTZdi6ufJEhufmUYnjs9HR0VABEQg6whQ4esbuI8h//d//+cqgz6RBxxwgJvE3Rd+hKWCh0WUkUqpUFK59PLzzz+74+xfuHChm05h2223NSwrjOKIfPTRR66C6a2q48ePd33NfBxUfLnen3/+aS+//LLf7ZZUeBs3bhzZl8z1fDxMTo/LLYIrI9YaRhllIvuwUMmmYovb50477VTkeDhsNq7Dmh/9GKnc04/xqquucpbZww47zDp06OCsZCWV9kmf/my7BIM5VapYclNNYOHdvF4Ne23qz3ZG27WjF5fU/ZR0vDwTfihaY8aMcQMkMYDSbrvtZkceeaRhVSefZpMwRyYjsmL9RDp27BjxqCDPHXzwwc6iiacFFmfeKRpUnnrqKevRo4dh5URQ3JMR+qSiVPItmTVrlnMB5v1kMCmuRfy4auN58OOPP0ai7Natm/vuYM3lWKdOndzosn6KlOiRZtu0aeMaFW655Rbbd999nTdKJLIyXsFjBZbJCCwqVaqU1I8GB76rI27qXSoKrE//bUHj2lFXXmW9g8bSO4NuEJKSI1ASjdAll9qyi1lKbNmx15VFQAREIC0CWEOpIOF2hzUjLFglvFAQXhi0oEcrlpdffrlz6SMc/WmvvPJKN5n9888/7091FV7mB9xggw2M/bgPemHahbBgdUHhZT4+4grL4MGDCymxyVzPx0OF2yuxfh8KXViJ5V6wjoWlS2AtuOOOO8K7cmKdeQxRLvjRvw/rHg0GuBlz37iN4+6Zyekhvv9puS1b/rdt2aBWiTOqv2lNe2/qLHv3qz9s7+1qp3U9LNQMsoQyw69GjRpursdq1arZhhtuaH6JQlAaguKEFZ2GIlzDcb296aabDJddflhts0HoB8u77CVaGUTBRHzl2TeCcU50/1Ufh1/SR5VvUiIhbsLhUsxzQ84555xIunh2vuFs/fXXLxQd27E8QK4OLJE03OFujNv3Y4895iy5hU4ug42S9qboFnwb9wis1KUtQ6660tqde55dGnx3GzZsWNqXz7vr+fcw7248yRuWEpskKAUTAREQgWwh4C0XWH7iCQoQCmyjRo2clY/BaHDfu/POO51Fhkq2FxRVKuBUyBlsCGsgSix923r27OmUXvqk4VZIxdxfm0LWVzzr1asXGaSIfnV33XWXj77IMt71igQuZgcWJBRYrK+4QJIO3AuxHqHIeutRMafH3I2ShMKOEoT1x1tHwuvRx9imsu/Dsh69zcX8oDQoDPHW/XHYYg3DdZJpLuCJxYmGiiZNmrhj3rIW82aS2PnKtJ9dqJrVqyQRet2CNKy3kYtg1u8rba19Pb348CTg2ZOf+YUHHEovxsyehcLIQET8tt56a9ewU9xUN5m9cvGx0W8U6z4NI1g5Ubq9kMd4xxmEDY8GBAsniiMu77zz9EPlnceVlPVmzZo57wy6NeAGjKL722+/FTtoFHFibaQhhu8XS6y0PDu+G4kEd2IaL4444gjbZJNNIg0XXJt3YYsttnAKOI1muCtvtNHavJYo3pI6jts24wLgfk1+4OfXUcaj9/lj7I8+zjF//KuvvrIF8+ZZr9NPK6mkJxXvwjmzpcQmRUqBSpKAlNiSpKu4RUAERKAECOD2i9SsWTNu7L6iyhQh3mJLJYhKKRWssBKLOzGDtiCnn366U2IZNAUllgohv+rVq7vjWAJjVTyppHo3ylq14lv24l3PXSSJvwkTJrhQuOGifCMXXXSRSz998NJRYkk/lfHvvvvOVbq5J35U6P0SZdmvh49H7/fnEAYrFJVTfr5SynLlypWRbV95dTcS54/nz/1VqVIl4h4aJ3jcQ/+sLggU7gpWbcOSt1xusdna/PrbkpVx0xTvIEo7v0svvTResLjHYA5rlrF+/jklWvrnSDi/jrv8Tz/95Czpixcvds8d18+yFhqy8JKAGwonDEkrgnWfAZj4TvBeY/nHKorg3rtixYrIeeybMWOG66OK8nvsscc6hRSvkP79+0e8JMIWJN4DL7fddpvrv4+lEqss6cKKGg7vw4b34aaN67ZvtKGhDQ8QujKErcAo42WtwPr0ey8Sv52J5V0BPxrulgTPsMa/zygT8SYbR8+gkaB1i+a2Xf3c7hKQ7P2WdbjwO1DWacnG60uJzcanojSJgAiIQBwCXoFksJZ44i22DELjhT5vKLHzgtb8sGDp8OKVYyqvJSWZuJ6/Pz+gFWn1ro+446YjWPmwYJeloBChGDHHJQ0JuI5jIeOZ4cKHcs5zRMFYV1l/PbPq1TI/InGsdHld5vfF6SuxseJNdR9WdX6ZUnZoEMKKyQ+LOXmIRiPc3vfcc89Uk5eR8PSZ54fV9M0333Rx0rUA993oijEK67XXXuu8GfAmCB/nW8MozIxsjFKOGzBhEAZpwpKKGzyNATTW0JADA4R+w8jRRx/tlvwRH4omVmEaY/y3BgsrPy/0+wwLlla8JDgHpdi7I+PCTbq4Lo1spAHBCk7f2/ImXYLGhuFBv+RrAq+YIQHD0pTx739gH3zxpY249VarkIT1vDTTVt6uFe3WX97uL1P3IyU2UyQVjwiIgAiUEgEGPEKonFJ5pEIeS+gjiHjLLeveauGPsQ/xFdO1W/H/UbLWVVK5HtfCuhUtvgKMNWezzTYrdDgdK2yhCMpwAxfNF1980f28Uo77Jf3/sEhlUurVrBxU/P+zlGUy7ui4Vq5cO7/nkuVlq8RGpyudbRRXXJp5B3Fpbdu2rZsWhj6yYQ+HdOJe13NuDZQMBkdDot+z6O3wtXCBL05QEmP1xUaBRYr7BhUXH4porPiKC+/3R3t4FJcuXO7pEuGF0aXLg9CI9VRgie0SWMCvCayitwYNE6UhWH5RnC/qfqrtx0B+/zZklMa1dQ0RKI6AlNjiyGi/CIiACGQpAQZlwZWPShr9W7FqUJmLFvqtIRMnTnRWIfphehfj8ABQ0ecVt+0rnVTgw4MrFRc+3f1+0BlGf6VFGssQil20MG8lyh6WJAbTyWVBWfWKKyO3IlRYcddkhNaSUsqbbbah/frbMvtrxSqrWqVoHsok05V/r1ViS3AQ5Ewmt0hcn3zyiXvnUF6xNuLCftJJJ7l3kX6Z2SK+kStb0lMW6UAhpz9yeZTmzZuvVWQDZTKYx6zEFVkU2AuCsQa2D0acvqJ3bn9ncyU/yBKb3JMq2RIruTQolAiIgAiIQIoEUFxRYpliBzdGlEqsIbid0t+UaTGYR/aee+4xRhPGJRW3O6atQBlNx9XOD+bEoCX0rd1xxx3diMTnnXees4SiLFPRR5iWB2FaHEYkRtE866yz3L5Ef1iJmS+SQWhOPPFEw/ri55nEffCBBx5wc0bSjw+Xxueee85dz4/ci9tt7969U7YOJUpXSRxHOec+mXqEdHOv9PPjXmioiGc5y2R65ixYZNs2rZvJKIvEtfKfVW7fQTsnHsinyMlltAMrK32vsbji2o2VlXcHV11cuktaeM98hbZ27dox+6KXdBryKX7eQT8PKu+ebwjMNgYospODaZO6BN+Kax962G4971wrKIHuHyiw3W7sjUnfnnpiVLZhKLfp8e98ub3BDN2YlNgMgVQ0IiACIlCaBBjZE4soyhpLP+0NrrWM1otgkXn88ceNaWi8UskALAyKwqBAiO//5pfF7WM/fWv79OljDM5Cxd4PrITCiTsvA7SgYIYFBY0fijNKrL+OXxLWr/sl+y655BI3WA7X4NxBgwY5qxfu0KNGjXJKLO7EjHLMiMuvvfaaGzCGcxEGqckm69jaVP33z+A5KP00LlAhpQ8llj1GkfX9/f4LXXJrrbeubXVrV7U5Py0pcSV24dIVztp7SA4psTTY0DBE/04GDSvtPq68W17OPPNM1z/Vb7Nk7mYUbKz24b6n4TAluY6b/7PPPusGU/OuxSV5vWTjxquBabkQBoPyXiT0Nef7gdB/Fkt6WJjX9YUXXnC7OMc3noXDZMs634mnglHg+XZc++Bwp8iuCUaPzpQ4BbbPzbZF0HBzZzAyeml+lzJ1D7keT7hMzPV7KYn0rxdo+wUlEbHiFAEREAERKD0CKHcopn5U0egrU6Gj0paJwWwoNpjahP64XM/3TY2+Zia2sR6TZvrQMXUG1hFcBcMjnnIdXKUZVZgllc9U++hlIq2pxEFDAunETZgpdMpSBo+bZWM++Mm6H72rVapYcv1jR7z4iW1Zr6r1P7X057csS77rcu3GjRvb6NGj3WBR0fGgVKOsMSASXhHJejpExxNvm3cdl3YGdwoPEOfPIW00ONGIRMNatsjAgQOdBwgKKV4OLf6dU5WBqGj4Y9A03PZZxhIax2iwy2Yl1qcb13amFNsraATre1p3q/FvA6U/ns5yafAd7fa/G6xG0HWFqY0kpUuAQcwYwZs8mIkB/Eo39aV3NVliS4+1riQCIiACJUbAWxqKu4DvZ1rc8VT20zqc6HqpxBcvbFhBjqeAo6D7UZvjxZctx9ZliphM38Npbbewp9+cba+/N9M67Nss09G7+L6Z9bvNm7/YLuzQqETiz7dIfR9q5kT200vBgEYcGnh4R1FAmXPYj9jLMdY5F5f9aCsP4ZctWxZp6GKbc/DioBGMdSQcX8eOHZ33QKx3D4WRxqRwg5NPHxZRrh9vMCl3sdBfdPo45Kc3ogHPp4v9KNY07HmrKvsQrMV4kuAd4vuerz2Su/+uj+y/c2N3mzPHRlzXa52m31kvYNTt8iusIHg+3sMnd+nkdsqj39HcvpvMp77kmlwzn1bFKAIiIAIiIAIikGEC1SpXsLa7bG6ffDnP5v+yLMOxB4rGP6vt3Y9nW8tmdazdDuVjlNiMQ0oxQtzQkeh+uTvssIONHTvWHXv55ZeNbYTpuJhuh770KD2Mds3AaQiKIH3nmROa7gb0xZ41a5brGuBHWj711FPd+cSBoCCyznGmywqPHo4ijAWJgdfo2/104PLqhVGcL7vsMtsmGCQIyy6uyImkuPRxHkoW98N9XnfddZFRmRPFWd6Oe0V27oIF1i0YfAlX4HRkvaBx49oHHjRcNGkgkQtxOhTX/RwabBC/XPcYy2cMUmLL53PVXYmACIiACIhA0gRO3re+6xs7+vXpSZ+TbMCx73xnCxf9aTccnz3upsmmPdvCLQiUlIsvvtj1aydt9Hdn2/d5D6c3VgUYSyijK9etWzfiJsqAVf3793dzwdK/FgVzTmDRw43RD9Q2dOhQ1zf4s88+c5dgkCkU6WeC6V6ihfiZ55W+pwxSdsUVVzgLL+GYnmvGjBlO0WbgOfqGJ5Li0sd5KNfvBQMc3XfffW7k9TFjxiSKrtwe94rsvGCO7HbnnW8zgoaIVOXa/xtmXwbPBwWWQfNwa5WUHQFZYuOzlxIbn4+OioAIiIAIiEC5J7B1/ep2S7cWzmUUpTNT8vqUmfbl1z9ZrxO2t0Z1184pmqm48zEe3IAZidz38WSdH0ppMsKI3oy4i9UVZRJhBHEGP2LwKqyrDGbFcVyBfTeE6tWru3Xv3k/lGkXWHw9fGyWWEZwZpOyMM85wh8KuuwxART9wwqAs43YcT4pLH+cwBzYDpOEezMje3godL77yfAxF9slAAeX5nBL0aU1Fkb12+EM2Lnh23gLLFEX0y0SZlZQugVgNUKWbgty4mpTY3HhOSqUIiIAIiIAIlCiBnZrUtJsDRfbzrxbYvU98YL8tjK9cFJeYpcv+Nn7Pvf6VfT5jvt3UvaXl0ojExd1XNuxHiWQQH5RMhHV+TULz1PoKMApetISVUH+MvqS4AMcTLKipCH1xEZ+WsEXJK77hvrLx4i4ufdwfozcz7Rauywwyh+uxFx+/T4vfzzKcnvD+8rDuFNnAhbtB/fp2wW23J+VafM2wYfZaMFWbV2DhQH9nRoVnDm5ZZMsmZ5TnfJoJolJiM0FRcYiACIiACIhAOSCw17a17cZTmttmtavY/U9+YJOmzUn6rv5c8U/Q9/VHGzzyPfersOZve6bXXlJgkya47gGxcI4fP95ZWRm5GKH/ajxhdOO33nrLRo4cabgrh62jVKLbtGnj+rXST5Z5VHFJXhHMSUq8XlEOr9Onljmsmb/aDwxEHOlKcemjHy6DVF1wwQXOisw6yjgjpyNYZhmAjnSQ7vBIxLhMI0xPxv0mYuQC59AfiuzTwfzZNQJrORbZ4vrIsv+Cfv0Ci+3a0Zo5LyxHHnmkc/nGIpsLiix50zeccB+xGjDC95et6+F7yNY0ZkO6pMRmw1NQGkRABERABEQgSwgctFM9G3HJrnbnebva7B9/tTuHv2MjX/rU3vpots2Y+ZstXLzCVq1aYz//vjzY/tUmf/KjPTn2Sxv48GSb99NCu6FbS/d76OJdbZMalbPkrvIjGcyPjELK3KHMF41ix0BK8QQF8+qrr3Zuo8yDu++++9rUqVMjp5xzzjnO2rn//vs7hRaFkKl1GFSKPq8Irsh77723W2cwJ9yWSctzgSJFv1c/9RdTZEULijJKJINPhX8///yzC1pc+lDYUbJQmknzLrvs4voGh0f+RsEdMmSIS/fgwYMjl8ZyjXJ84oknunNhVt7EzSMb9FleL2B+VDDacLRrMdv0nX3/y+n2VBCuuEGccP+mzzSKLFODZavQRxt3+GGBVRmhgWL33XfP1uQmlS5ZYuNj0jyx8fnoqAiIgAiIgAjkNYFJ03+zKd8ttg+++t3mzF8ak0XrHTez/VvUsWP32Czmce1MjwDzxHo57bTT7MYbb/SbxS5XrVrlrFG407KO4uhda4s96d8DWDGZroa+t2HBwsU0O/Hmog6HZx3XXq6dTEWcAZro2xqWzTff3KZMmRLe5ays0enDKuyV41j3iyv0n3/+GXM+a5R80ufvF6WXUZ0RrLi5ME9sIUAxNpYsWWJdjjrKZnz/vV17+ul26uGH2eCg3+w9Tz7lQjMPLI0XiYRwjG7do0cPCzcUJDqvtI6jxB4V3Cf5BgWWvMNcyuFnGGvap9JKXyrXYWooBmy75ZZb7KSTTkrl1LwKq3li8+px62ZFQAREQAREIDUC+zava/zsiK3sh5+X269L1vY7bLZ5NatdfYPUIlPolAjgluvF92f128UtK1b8r2oXnju1uPDh/QzWFEuIJ9W5oVOZA/aRRx6Jddki+2KlD6XWS6z7RcEtjp23EPvzmaYHJQ2JFZcPl0tLZ5ENLOdnBNbxW4YPdz/Sz7zbDzzwQFIKLOG7du3qXMmvueYaNrNSkSVdzAU8adKkSMMG+3Azx4rM/WKtxarsvQg4nm3iG378MtvSly3p+e9Lly0pUjpEQAREQAREQASykkDTetWMn6R0CDBCrKT0CGDFK4+CIvt00Ef6qcces2cDK1/zFi3cyNENGzZM6XZxv6aR5Morr3TnZaNFFo+Fx4L77N69e+TewtM+YbFl2qcOHToYo25no6hPbHJPRUpscpwUSgREQAREQAREQAREQARylkCXwDWV37oIo2Fj3fYW62xTZOknff3117u+0v4+w9M+0Zf79ttvN6Z9YpqnbBZZYuM/HSmx8fnoqAiIgAiIgAiIgAiIgAiIwL8EGOwJi+yFF15oDRo0cNM8ZQscXMdxfR4xYkShJPmRir2VM5sVxFxIYyG4ZbQhJbaMwOuyIiACIiACIiACIiACIpCLBDp16uQssoxeTd/iww8/PGtuA7dnLLK+HzcjWPfs2dNNt/Tpp5+6dK7LtE9Zc6N5nhBNsZPnGUC3LwIiIAIiIAIiIAIiIAKpEmAqpwcffNANlJQN88j6gbp23nlnYwomL/GmffJhsmkpS2xyT0NT7CTHSaFEQAREQAREQAREQAREQASiCDA9EtMk3XXXXXbMMcdEHf1vc+7cuZbqYFL/nb3ua6lM+7TuV0s/hueff971Oe7Xr59zjU4/pvJ9piyx5fv56u5EQAREQAREQAREQAREoMQItG3b1h5//HG77LLL3DQ2xV2IeU+ffvrp4g6X+H6mfcrmvrAegCyxnkT8pZTY+Hx0VAREQAREQAREQAREQAREIA6Bvffe201t06dPHzcna6yg9Ju9++67bcGCBbEOa9+/BLwSKyDxCUiJjc9HR0VABERABERABERABERABBIQ2GeffWzYsGFOUR0wYECR0Cixm266aVxrbZGTtEMEiiEgJbYYMNotAiIgAutKoG/fvusahc4XAREQAREQgZwhcMghhzglFotrLEWWPrMPPPCAffLJJzlzT6WdUFlikyMuJTY5TgolAiIgAkkRWLx4sRutccstt7TRo0cndY4CiYAIiIAIiEB5IcA8sjTiosgOHjy40G116dLFmjZtag8//HCh/dooSiAX+u8WTXXp7dE8saXHWlcSAREoxwRoVX7ppZfsoYcestWrV7s7veiii8rxHevWREAEREAERCA2gZNPPtn+/PNPp8xWqlTJmE8WYXAlrLH9+/c3lN39998/dgR5vFeW2OQevpTY5DgplAiIgAjEJPDGG2+4URlff/11N+F748aN7Z9//jEssd26dYt5jnaWDwJ//fWXrVmzxj33eHf0448/2ptvvumCML1Eu3btIsE//PBDmzFjhttu1apVobkNI4GyfGXq1Kn27bff2vHHH19iKY3HsMQuGhUx03OMGjXK7a1QoYKddNJJUSG0KQIiECZw9tln2/Lly41RiVFkTz/9dHf4xBNPdH1nscZKiQ0TK7wuS2xhHtFbcieOJqJtERABEUiCwEcffWRnnHGGK5TnzZtnl156qe2+++62/vrr22+//WbnnXdeErEoSC4SmDlzprMkbLfddta8eXM74ogjjDxQnCxbtsymT5/urPReCfJhf/nlF3fstttusw8++MDvLvUlLf9YR9Lpp8aUGTfddJNT6Esq4fEYJromo6Uy/ce6Ch4WPMcxY8bYtddeu67R6XwRyAsClI09evSw3r1724gRI9w916lTx31vJkyYYC+++GJecEjlJmWJTY6WlNjkOCmUCIiACDgCc+bMcQoqFf7KlSvbE088YWPHjnWV//fff986depk++23n+21114iVg4JYI3DioC1Hdfxt956y1q0aGFVqlRxbuQoWxwLy/bbb28oqWELrD/OaJ0cq1+/vt9VZInFF2WXuBNVbrAMo2yxRLCCRMuKFSts1apVkd3EyTk0zCxatMite5f4ePH582688UZ79913XQNOJNLQSnQawukjmI+HdY6lypDzihPi+/rrr23u3LmF7iscPjp9/hiMVq5c6TetatWq7ll17949sk8rIiACawnMnz/fzj//fFcm/vHHH4WweEX2+uuvd9PwcPDUU091YR555JFCYbXxHwFZYv9jEWtNSmwsKtonAiIgAlEE3n77bVdA77vvvs4tihbke++919q0aeMKY5QMWpQpkLt27Rp1tjbLCwHyAXMc3nzzzU4pbdKkid16662GZeHjjz92Cm2zZs0MNzostusiVAqx8mLxxdUYZXn27Nlxo7z66qudKzuWURpasBRfccUV7hzv1rfrrrta69atnTsfBxgpdKuttnJhqFjiCs8PiRffa6+95sJtu+22Lp3uhNDfDz/8YBdffLFLA8r6xIkT3VHYXHLJJZGQDPzCHJNIJhl++umnLn2TJk2yIUOGRO7r888/d9fi+VDphtEJJ5zglHh3IPgbPny4MV3ILrvsYv369TMaLyQiIALFE6Ah7oADDrAnn3zSLXnHGdzQN+p5RRYvhkcffdQN7nTkkUe69w5vDokIpEpASmyqxBReBEQgrwhQCKNInHLKKU5RYfCmQYMGRSr97KdyjlWOghgFpn379nnFKJ9uFiWyWrVq1rJlyyK3veOOO9qUKVNcxQ0LII0c6yIjR4607777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+WnFmtyuuXa7/KfVZvRrsw1eyfeft7NptkX5BXTCdfjkk08uMwGbKyu1r7wEeHv6xNChZtw70w0uv/kq69rQ+ghY3Ij69OljuI6KCIiACIiACIiACGCwSZKA9Ss9JWLj/zYlYuP5ZKxtUndj88iFbUynvRuYrxYtNyNfmW3ezTHY09z5S82YCbPNtvU3NvedvZOpt2n5+eFnnLAaiEApE9jRrk254/rrzLMTJ+VFyK5lg231vutuJ2AvueSSVJCuUp6GuhcBERABERABERCBYhPwYrbYHVTyE+VOnIcbvM7aa5k+x29vGm2+kfn3819Yd8V55gObfmfn7RuYXVumd9tc/duf5sN5i82sT78zS22+2eM7NDSXH7kmHUoehqQuRKBCE+h04knmtv8uN71uv93MWfClefyGfqbm35Gfc53YNQ8/4gQsicsbNWqU6+lqLwIiIAIiIAIiIAJlRsCLV1li45FLxMbzyan2Hwc0NttsUd28+ckPZursH5yYJZfsJjU3MtU2Wt+sv946ZqVNy/PzL785q21ta3E9YJe65qAdW5hdmm6a07XUWAQqO4FuNoLy3AULzBDrAkz6neII2fteedUJWNIUkQ6JNEzkyw2mJ6rsHDU/ERABERABERABEahsBCRi83xH92u5ueHHHGPMhwt+MpM+Xmo+XrjCbGQdtzdeZ11Tr846pnrDmqZVx63Mga0VgTfP+NVdJSPQb8AA87NNHTTK5uvNVciOnjHD3GPD6pPb+M4773Rkli5d6vL58kFCtpL9sWg6IiACIiACIlAJCMgSm91NlIjNjlOxWu3UZBPDj4oIiEDxCRCxeK111zWExc9WyN7y+ONmyHNjzAArgo877rjUxRGuDWyQpyuvvNIdk5BNodGOCIiACIiACIiACFQYAgrsVGFulQYqAlWXAJbUBx54wHy7bJnN83qfWfHLL5EwiGr8mo1u/PLLLxcSsP6EE044wQwePNhZZO+++25/WFsREAEREAEREAERKHcCssRmdwskYrPjpFYiIALlTOCQQw4xU996y3zz0wrTo2+/tELWCdgZM81T1mobl0aHHMiDrNgdOHCgS2xezlPT5UVABERABERABERABHIgIBGbAyw1FQERKF8CNWvWNE/ZQE8FG2xgjrqyl5n75ZepASFgScvz0MMPG3IdZypdunRxa2WTIGT/97//Gf/mlXH/9ddfmYavehEQAREQAREQgUpIwD8PKDpx/M2ViI3no1oREIGEEXBC9qmnTM1atcxRl19helv34lP79HECljWwe+65Z9YjJuhT//79y9Ui+/7775umTZs6d2kGPnXqVLObzZWrIgIiIAIiIAIiIAIikJ6ARGx6LjoqAiKQYAJeyJ5++ulm+qfzzFobbGhGjhyZdg1spmmcfPLJpo8VweVtkX300UcNFtl05ddff5V1Nh0YHRMBERABERCBSkpAltj4G6voxPF8VCsCIpBQAghZxCc/JS2I4d9++83ceuut5vfffze9evUqaZc5n7/RRhuZKVOmmPXWWy917sqVK92a3YceeshZa3v27FksoZ7qUDsiIAIiIAIiIAKJJuDdiRM9yAQMTpbYBNwEDUEERKD8CZx33nnmkksucZGL+/btW+YD+sc//mGGDx9e6LoTJkwwTzzxhHnyySedeL3iiisMwlZFBERABERABESgchOQJTb+/krExvNRrQiIQBUiQN5YhCyuvWVtjT3yyCPNuHHjzKJFi1LEEbEdO3Y0e+21lznjjDPc8WnTpqXqtSMCIiACIiACIlC5CMgSm939lDtxdpzUSgREoIoQQMhSWCPLWtR77rmnTGa+ySabGHLYDh06tND1fKRi/5+a3swWwqMPIiACIiACIlApCej/+/jbKktsPB/VioAIVEEC3iI7ZswYc/bZZ8cSuPvuu2Prc6k86aScIvGmAABAAElEQVSTzOzZs1OnHHTQQWb8+PFm8uTJ5sEHH3TH995771S9dkRABERABERABCoXAf/SunLNKv+zkYjNP1P1KAIiUAkIeCH76quvmlNPPTVyRu+884657bbbIuuzqahWrZprtvPOO5vtt98+dcqBBx5oTjnlFHPuueeaZ5991lmHfdtUI+2IgAiIgAiIgAhUOgKyxMbf0rWs2i+Ib6JaERABEai6BLC04lrMulQCLIXLK6+8Yi688EIzevRo06pVq3B1Xj4TMZmoxfoPLS841YkIiIAIiIAIJJaAf+7gmYNnD5X0BMrdEktexKjciOmHnPnon3/+ae6//37z1VdfpW2Mbmfd2bfffpu2XgdFQAREwBPAIktU4Lfeest069bNH05tDz30UNO8eXODmC2tsv7660vAlhZc9SsCIiACIiACCSSgF9fxN6VcRewXX3zhch82bdrUtGnTxvCwuGTJkvgRZ1H7/fffu3yPrCNLVwiUct1115n58+enqy7xMUTyscceaz744IMS95WkDm688UYzYsSIJA1JYxGBMiGApbV3796RQrZLly4usnCZDEYXEQEREAEREAERqLQEvJOsRGz8LS5XEeuH9txzzxlyNGLpIFeij8ZJ/erVqw2W1XQFFzuihwYLVt369eubGTNmGIKkBAv9Ll++PHio0P4vv/xS6LP/8Mcff5hly5aZH3/8MaPVmD88xjBz5sxU+7Clmfn89ttvvvust+HxMZ8gK/bD18qFnx+7HxB9+X9I7H/66acu/Qf74etwTnh8vh9tRaAyEOA76pprrkkrZEmPw3fExIkTK8NUNQcREAEREAEREAERSDSBRIjYbbfd1px11llu3RmROd977z0niPr37+8stLvvvrt54IEHUiC/++47c/311xuCoLRo0cLlT/Ri9pBDDnHW3bZt25qxY8emzvn444/Nbrvt5s7BqhIsCxYsMBdddJFp2bKl6dy5s5k0aVKq+tprrzXbbLON2XXXXc1OO+3kgqukKtPsPPTQQ6ZZs2aupkePHilLs2/6yCOPmH333dfssssu5vbbbzcI8UwlanzDhw83TZo0cW7Rq1atMu3atTM333yz6w5BmSu/YcOGGaKh+tK+fXu3BvDDDz9085gyZYq57777UnOaNWuWaxo1Pt+PtiJQWQgQqbhv375FhOwWW2xhjj/+eDNkyJDKMlXNQwREQAREQAREoBwIeAOSLLHx8BMhYv0QEXaUhQsXmtdff908//zzzn31rrvucuIMSwflscceM9OmTXNbrLhYSpcuXerqRo0aZd5//30TjuCJQGPd2htvvOG2rvHfvx5++GHz888/mwkTJhjWt910002uBpH2+OOPm3//+9/Osop78OGHHx48tch+9+7dU27ErMtFAH700UeuHWtw+/XrZy655BIzePBgJwinT59epI/wgajxEbUUoXn55Zc7wbrBBhuYK6+80p1eHH7+H034+jvssIObBy8TzjzzTLfPvHwU1ajxhfvRZxGoDATwFuE7As+RE088MTUlRCz/nt9+++3UMe2IgAiIgAiIgAiIgAjkn0CiROw666zjxCfutq+99prZeuutnQAkQBOiFEsgLrNPPfWUQSxibUX4EqSpUaNGjs4mm2xiateuXYQUaTK6du1qGjdu7M71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h7PEYjVlbVe1atXczE8++WRnRSV3Iu3iyt57722mTZtm+vfv79JOsPaMwoMfQnbTTTdNe/p2221natWqZXAzrlOnTiFBeNRRRxksuARMosyYMSNtH/4g7bAkE/jpnXfecYf33HNPX512O2nSJBccCkH/7rvvGsTwhAkTUm2xCGNh7tSpkzuG2+DChQsN4vfUU0916Te6deuWaq8dERCBZBLge4x/u+l+/Es8litQ7z1JmAkeHRw77LDDUhPr3r27wZuF7yRetp155plmzpw5pm/fvqk22hEBERABERABERCBJBOIjgCS5FFnMTYEJAWX3kylV69epkOHDs4y+cADD5jhw4ebV155JdNpsfWI22DxgZO8ZQQxHiz77ruvqV+/vnnxxRfNvHnzzJFHHmk23HDDYJMi+6xpRbwTnIl+iTIanK8fg7fC0IFfe+uDuUQJ9CIX0wEREIFKQ2CdddZxL738hPzLP/9ZWxEQAREQAREQgfIhIEtsdtwrnIhFrGFVGDFihBNsjzzyiHPlJf0EbrgrVqxwM2cdLA9mmYQgjbFKEPCkYcOGLiDToEGDXNAjhB59Ll++3PWJYCS6pxeH7mDELywnrFXFWkrZY4893JZzGSuuv1h5//zzT7P11lu79DZYj3HxwxqLm3CmgmsghTQaiF7GVr169djTWHuLWCZVB1YaXI5VREAEREAEREAEREAEREAEkkPAi9nkjChZI6lw7sTgw/0N4cea1FWrVrk1oRy/9dZbDQFLKG3atHG5Xd2HDL9wTUYQ4nqLgO3du7epUaOGee6551w/PhgKbrlBV72ghdNbWP2lyMuIcGW9LWvQatas6avM+eefb+677z6DGzPX86Vr165m7ty5zt2XoFGZys477+zWABNpdL/99nNz8O7E4fHQlx8vgVywNDPnkqYNyjRG1YuACIiACIiACIiACIiACGRHwItX/9ye3VlVr9VaFtSaOM4VcO6rV6/OytKaaWpYQ7Hckl8RSyaudiUprGW99NJLncjmDzBd3kbcixHgWFF9YRxEWyaacL9+/fzhrLZYjHFRRnxnU2hLCiDW/+Ji7N2LszlXbURABERABERABERABERABPJPgGWOTz75pPPmJPCsSnoCFc6dODiNbFyFg+2j9hGZuPjmu8QJQ+q8gF26dKm55557XIoejl1wwQU5DyXXNW1Yaj2/dFbbnAegE0RABERABERABERABERABPJCQJbYeIwVWsTGT638as844wyXtzXbEWAMR0iSA/Lwww9Pidtsz1c7ERABERABERABERABERCBik+gAjvJlil8idhSwE0O1lwKqXFydR/OpX+1FQEREAEREAEREAEREAERqDgEZImNv1cVMrBT/JRUKwIiIAIiIAIiIAIiIAIiIAIVj4AssdndM4nY7DiplQiIgAiIgAiIgAiIgAiIgAiUCQFZYuMxS8TG81GtCIiACIiACIiACIiACIiACIhAgghIxCboZmgoIiACIiACIiACIiACIiACIiBLbPzfgERsPB/VioAIiIAIiIAIiIAIiIAIiECZEPBrYiVi43FLxMbzUa0IiIAIiIAIiIAIiIAIiIAIiECCCEjEJuhmaCgiIAIiIAIiIAIiIAIiIAJVl4Assdnde4nY7DiplQiIgAiIgAiIgAiIgAiIgAiIQAIISMQm4CZoCCIgAiIgAiIgAiIgAiIgAiIgS2x2fwMSsdlxUisREAEREAEREAEREAEREAEREIEEEJCILeObsGjRItOzZ88yvqouJwIiIAIiIAIiIAIiIAIikHQC3hKb9HGW9/jWLe8BVLXrd+zY0axataqqTVvzFQEREAEREAEREAEREAEREIG8EJAlNi8Ys+vkxx9/NL/88kt2jdVKBERABERABERABERABESgShHwlljliY2/7RKx8XzyWvv666+bDTfc0PDHOXbs2Lz2rc5EQAREQAREQAREQAREQAREoCoQkIgtw7v8xBNPmC233NKsu+66ErFlyF2XEgEREAEREAEREAEREIGKQECW2OzukkRsdpxK3Oqzzz4z06dPN3Xq1DHrrbeeE7Hz588vcb/qQAREQAREQAREQAREQAREoHIQ8CK2csym9GYhEVt6bAv1/Pzzz5tddtnFidgNNtjAVKtWzUyYMKFQG32oegR++ukn515e2jN/9913zZNPPpn2Mn/++aeZNGmSufvuu83MmTPTtsnm4KhRo8ynn36aTVO1EQEREAEREAEREAERiCGgNbExcGyVRGw8n7zU/vbbb+bZZ581BxxwgHMlXmeddcwRRxwhEZsXuhWzk5deeskcdNBBpnXr1maHHXYww4cPL9WJPP300+aGG24wf/31V6Hr/PHHH2b33Xc3l112mfn222/NihUrCtWn+3DjjTeaESNGFKm64447zAcffFDkuA6IgAiIgAiIgAiIgAhkR0CW2Ow4ScRmx6lErV599VVDflhELK7ErIlFwLz11lvm448/LlHfOrniEcDyiaDs1KmTs3z27du3iLhcvXq1oV26kkuEa74I//e//xmuMXXqVLP22oX/yc+YMcP88MMP5s033zSIUP5G4wp9YW3l75l9fsKFlza///57+LCb46+//lrkeNQB+oYB5/htsC2CPKo/ji9ZssSsXLmykKUbHj///LOrC55LuyjeXGf58uXu0unmm8v9CI5f+yIgAiIgAiIgAiIQJuAtsH4brtfnNQQKP9GKSqkQQCDstddeplWrVilLLCK2efPmssaWCvFkd4rA++6778wWW2zh3MuPP/54c+qpp7pBI4j69+9v2rRp4yykDzzwQGoyCxYsMBdddJFp2bKl6dy5s3MBTlVG7IwbN840bdrU/a1h/Q8XXqTsvffeZuONNw5XFfn84Ycfur6mTJli7rvvPrdP37NmzUq1feWVV8x2221ndt55Z4N7sS9Dhw417dq1My1atDDXXHNNxlRTCGX63nfffc2uu+5qDj/8cHfu119/7bqM6g9rMvPkOm3btnVW7oULF7pzgv8Oqdtnn33cccQr1vBmzZqZM844w0yePNkP271k2m233dx8YL/jjju6lwE0KM79SHWsHREQAREQAREQARFIQ0CW2DRQ0hySiE0DJd+HeHj2Fi6ssLgTU7p06WLGjx+f78upv4QTQDBeeuml5qqrrjJnnXWWmTdvXmrEpGFi/TTuunfddZe5+eabzbJly1z9ww8/7KyIrKU+9NBDzU033ZQ6L2qHv7v333/fCcdgG/4mEWXPPfecs6yyz4+3OAbb+n2EHkIW9+MzzzzT7fN5++23902chfONN94wPXr0MAMHDnTHEezXXXedufbaaw1u1IhErp9N6devnxO855xzjms+Z84c9wIgqr9hw4aZzz//3F0H12bWAjds2NCde/vtt5smTZoYxvfRRx+Z1157zR3n3yNB1xD8vFi68sorUxZm+uMY5yByecng/3Mpzv3IZs5qIwIiIAIiIAIiIAKyxMb/DUjExvMpcS0P699884058MADXV+4E3sRi3WJh3L/MF3ii6mDCkPgkksucUL1xx9/NAcffLDBgknhb2Hrrbd2Iuurr75yAcCwfOLSigCsV6+emTZtmvsb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119/vcsL26JFC0OOVcRs06ZNnUD+8MMP3T6fH3nkEXfeuHHj3DECJx1xxBGpvthh7oSZ5zonnniiyzPLcXIqH3TQQYY8ubBgm42YJU9uuvEhXmHerFkzN2ZS6KiIgAiIgAiIgAiIgAgkl4BEbDncG4nYcoCewEuyBhoRWbduXTNy5Eg3wtatWxuiWj/33HPOYhmMhnv77bebJk2amDfeeMN89NFHJcorjCC+6KKL3HU+/fRTt89ncr/6N4DpkGGFJdXMww8/bO69914zZMgQ8/3337umjz32mJk2bZphy/j5O1+6dKkbK30jOBGy/JxyyinuHCyZCPdrrrmmyOUefPBBs3jxYidaYXXLLbe4NowPgXvIIYeYV155xfACYNKkSUXODx+IGh/rXadPn24Q1IjpK6+8spAlOtyPPouACIiACIiACIhAaRHwz2GyxMYTloiN51MqtRKxpYK1wnWKBZHItfvuu6+ZO3euGz+Wy5kzZzoRSP5R1or6gsUUkdi/f3/z/PPPm0x5Zv156bZbbLGFuy45TxGIjIGfYI7UdOdxDMssFuFOnTq5JqSGQtwSQIqcx23btjW77LKLGTp0qGnUqJGLzItr7nrrredyuJLH1V+HY1y/evXqhS7nxTIBkRD2PXr0cFyItOwL18Ktd8cdd3RBofzxdNu48eHejJAfM2aMcyvGYuvvR7q+dEwEREAEREAEREAERKB8CSg6cTnwl4gtB+gJvKSPTBx804arLms2SeuCuAqWXr16mQ4dOpgpU6aYBx54wAwfPtxZIoNtst3HXZmfefPmOUF5/PHHpz2VMQSFI41q1arl2gbHzQFEdXj9qmtofyHIV69e7T+WeFutWrVUmiD6zqZEjW/06NHmzjvvdALczy34bzQ8z+C1qAvfp2C99kVABERABERABESgOATinj+K019lOye7p7/KNutynk84gEw5D0eXTwgBrIW42h577LFunacfFkGRKLjQNm7c2Jx00klu/SjWwmzWgvp+st0ibrkWQZ+eeeYZJ0yXLVtWJPBRsD+EJOPGZRd3Y9rThy+77rqrs27i9ouLsRfGBFRin3kgHNnnGP0ddthhZsSIEYb0O6yhJfXPZptt5rvMaRs3PsaEZfn0009P9Y811v87JdowhcBTX331VWrsHMP9GHfoBQsWOGtuUPxSryICIiACIiACIiACuRDw7sS5nFMV20rElsNd14NuOUCvAJdEaLEe86abbjIERvIutj7fMK61pMPh86BBg0zv3r1NjRo1SjwzrhssXIPASV27dnWWXtayDhgwwK09DbflPP+mEPfezp07m0svvdQgWrEar1q1ynXdpk0b1x+BmhCjPm/t1VdfbajDRRrhyD7HKGeeeabB3fmYY45x/Vx77bXuuL+e+/D3L38MwR/+YZ0vJWp8HGdtMoKUNba4Qp933nluvpzHiwOCTvHygDy6rEn2hc+4TLdv39507NjRfPPNN75KWxEQAREQAREQAREoNgH/bFPsDir5iWtZtV9QyeeYqOndfffd5qGHHnLpRhI1MA0mMQSwAGKVxf2VNbJsCT7EcXLMrrvuuk7gciybcv/996dEI+2xbAZzxUb1wbVZy/rbb7+563PdbIofZ82aNd062OA51JGLlrps+8MNecMNNwx2k3YfZgS+ChfEPyLcl6jxIbg33njjyPniKs1/KLQJF+4LrLhXrK9F0PrCtRmDigiIgAiIgAiIgAhkIsBL/Ndee83Mnj07L8aKTNerqPXZPZVW1NklcNw8aPMQrSICUQSC4g5h5AvHi+NOSwApLKu+EFgpm+Kv7YMwZXMObeLGSR2BnHIp2QhY+sNKvHDhwoxdR43Pi9Oo+bION6r49c3UI6THjx+fakr0aRUREAEREAEREAERyIWALLHxtCRi4/nkvRYRK3fivGNVhzEEEI25CseY7lSVgQDW2G233TZDK1WLgAiIgAiIgAiIQFECcpItyiTdkcKL4dK10LG8EkDEEs1Uf6B5xarOREAEREAEREAEREAERKDSEJAlNv5WSsTG88l7LSKWImts3tGqQxEQAREQAREQAREQARGo0AS8octvK/RkSnHwErGlCDdd1z6npERsOjo6JgIiIAIiIAIiIAIiIAIiIEts/N+ARGw8n7zX+rcqCu6Ud7TqUAREQAREQAREQAREQAQqNAGvFSRi42+jdnG0ygAACmJJREFURGw8n7zXyp0470jVoQiIgAiIgAiIgAiIgAiIQBUiIBFbxjdb7sRlDFyXEwEREAEREAEREAEREIEKQkCW2OxulERsdpzy1sr/YWpNbN6QqiMREAEREAEREAEREAEREIEqREAitoxvtncn1prYMgavy4mACIiACIiACIiACIhAwgl4g5fWxMbfKInYeD55r5U7cd6RqkMREAEREAEREAEREAEREIEqREAitoxvtrfEyp24jMHrciIgAiIgAiIgAiIgAiJQQQjIEht/oyRi4/nkvda7CEjE5h2tOhQBERABERABERABERABEagCBCRiy/gme3dirYktY/C6nAiIgAiIgAiIgAiIgAgknIA3eMkSG3+jJGLj+eS9Vu7EeUeqDkVABERABERABERABERABKoQAYnYMr7Z3hIrd+IyBq/LiYAIiIAIiIAIiIAIiEDCCcgSm90NkojNjlPeWvk/TInYvCFVRyIgAiIgAiIgAiIgAiJQKQh4rVApJlOKk5CILUW46br27sRaE5uOjo6JgAiIgAiIgAiIgAiIgAhoTWz834BEbDyfvNd6EStLbN7RqkMREAEREAEREAEREAERqNAEZInN7vZJxGbHKW+tJGLzhlIdiYAIiIAIiIAIiIAIiIAIVEECErFlfNO9iJU7cRmD1+VEQAREQAREQAREQAREIOEEZInN7gZJxGbHKW+tvIiVO3HekKojERABERABERABERABEahUBLQmNv52SsTG88l7rVLs5B2pOhQBERABERABERABERCBSkFAltjsbqNEbHac8tbK/2HKEps3pOpIBERABERABERABERABCoVAVli42+nRGw8n7zXendirYnNO1p1KAIiIAIiIAIiIAIiIAIVmoA3eEnExt9Gidh4PnmvxZ24ZcuWRpbYvKNVhyIgAiIgAiIgAiIgAiIgAlWAwLpVYI6JmuLSpUvNr7/+aiZNmmSmTZvmxubftOSy5S1NLu25ULr2+ejHA07Xf9R1w+eEP+faF+3zMZd89VPS+fjz2RaHhT+vIjHxY47bUkepbEzWzEq/RUAEREAEREAEqjqBn376ySHwzzpVnUfU/CVio8iU0vE+ffqYJ554wowdO7aUrqBuRUAEREAEREAEREAEREAEKiqBzp07V9Shl9m417KWmoIyu5ouJAIiIAIiIAIiUISA/6843dZ7iHBSuvpsjvsLFvd8f162/WQaU9ycMp3r6+P68OPNtM12PmXRT3A+fo65boN9ZBpzVH3SmOTKINw+H0xglY9+iss2OKfi9hG83/mYS3kxCbLwc6psTLp3724kYv1djd5KxEazUY0IiIAIiIAIiIAIiIAIiIAIiEDCCCiwU8JuiIYjAiIgAiIgAiIgAiIgAiIgAiIQTUAiNpqNakRABERABERABERABERABERABBJGQCI2YTdEwxEBERABERABERABERABERABEYgmIBEbzUY1IiACIiACIiACIiACIiACIiACCSMgEZuwG6LhiIAIiIAIiIAIiIAIiIAIiIAIRBOQiI1moxoREAEREAEREAEREAEREAEREIGEEZCITdgN0XBEQAREQAREQAREQAREQAREQASiCUjERrNRjQiIgAiIgAiIgAiIgAiIgAiIQMIISMQm7IZoOCIgAiIgAiIgAiIgAiIgAiIgAtEEJGKj2ahGBERABERABERABERABERABEQgYQQkYhN2QzQcERABERABERABERABERABERCBaAISsdFsVCMCIiACIiACIiACIiACIiACIpAwAhKxCbshGo4IiIAIiIAIiIAIiIAIiIAIiEA0AYnYaDaqEQEREAEREAEREAEREAEREAERSBgBidiE3RANRwREQAREQAREQAREQAREQAREIJqARGw0G9WIgAiIgAiIgAiIgAiIgAiIgAgkjIBEbMJuiIYjAiIgAiIgAiIgAiIgAiIgAiIQTUAiNpqNakRABERABERABERABERABERABBJGQCI2YTdEwxEBERABERABERABERABERABEYgmIBEbzUY1IiACIiACIiACIiACIiACIiACCSMgEZuwG6LhiIAIiIAIiIAIiIAIiIAIiIAIRBOQiI1moxoREAEREAEREAEREAEREAEREIGEEZCITdgN0XBEQAREQAREQAREQAREQAREQASiCUjERrNRjQiIgAiIgAiIgAiIgAiIgAiIQMIISMQm7IZoOCIgAiIgAiIgAiIgAiIgAiIgAtEEJGKj2ahGBERABERABERABERABERABEQgYQQkYhN2QzQcERABERABERABERABERABERCBaAISsdFsVCMCIiACIiACIiACIiACIiACIpAwAhKxCbshGo4IiIAIiIAIiIAIiIAIiIAIiEA0AYnYaDaqEQEREAEREAEREAEREAEREAERSBgBidiE3RANRwREQAREQAREQAREQAREQAREIJqARGw0G9WIgAiIgAiIgAiIgAiIgAiIgAgkjIBEbMJuiIYjAiIgAiIgAiIgAiIgAiIgAiIQTUAiNpqNakRABERABERABERABERABERABBJGQCI2YTdEwxEBERABERABERABERABERABEYgmIBEbzUY1IiACIiACIiACIiACIiACIiACCSMgEZuwG6LhiIAIiIAIiIAIiIAIiIAIiIAIRBOQiI1moxoREAEREAEREAEREAEREAEREIGEEZCITdgN0XBEQAREQAREQAREQAREQAREQASiCUjERrNRjQiIgAiIgAiIgAiIgAiIgAiIQMIISMQm7IZoOCIgAiIgAiIgAiIgAiIgAiIgAtEEJGKj2ahGBERABERABERABERABERABEQgYQQkYhN2QzQcERABERABERABERABERABERCBaAISsdFsVCMCIiACIiACIiACIiACIiACIpAwAhKxCbshGo4IiIAIiIAIiIAIiIAIiIAIiEA0AYnYaDaqEQEREAEREAEREAEREAEREAERSBgBidiE3RANRwREQAREQAREQAREQAREQAREIJqARGw0G9WIgAiIgAiIgAiIgAiIgAiIgAgkjIBEbMJuiIYjAiIgAiIgAiIgAiIgAiIgAiIQTUAiNpqNakRABERABERABERABERABERABBJGQCI2YTdEwxEBERABERABERABERABERABEYgmIBEbzUY1IiACIiACIiACIiACIiACIiACCSMgEZuwG6LhiIAIiIAIiIAIiIAIiIAIiIAIRBOQiI1moxoREAEREAEREAEREAEREAEREIGEEZCITdgN0XBEQAREQAREQAREQAREQAREQASiCUjERrNRjQiIgAiIgAiIgAiIgAiIgAiIQMIISMQm7IZoOCIgAiIgAiIgAiIgAiIgAiIgAtEEJGKj2ahGBERABERABERABERABERABEQgYQQkYhN2QzQcERABERABERABERABERABERCBaAISsdFsVCMCIiACIiACIiACIiACIiACIpAwAhKxCbshGo4IiIAIiIAIiIAIiIAIiIAIiEA0AYnYaDaqEQEREAEREAEREAEREAEREAERSBiB/wPpG/8ocYPdfAAAAABJRU5ErkJggg=="
}
},
"cell_type": "markdown",
"id": "dc949d42-8a34-4231-bff0-b8198975e2ce",
"metadata": {},
"source": [
"## Nodes and Edges\n",
"\n",
"Each node will - \n",
"\n",
"1/ Either be a function or a runnable.\n",
"\n",
"2/ Modify the `state`.\n",
"\n",
"The edges choose which node to call next.\n",
"\n",
"We can lay out an agentic RAG graph like this:\n",
"\n",
"![Screenshot 2024-02-02 at 1.36.50 PM.png](attachment:f886806c-0aec-4c2a-8027-67339530cb60.png)"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "278d1d83-dda6-4de4-bf8b-be9965c227fa",
"metadata": {},
"outputs": [],
"source": [
"import json\n",
"import operator\n",
"from typing import Annotated, Sequence, TypedDict\n",
"\n",
"from langchain.output_parsers import PydanticOutputParser\n",
"from langchain.prompts import PromptTemplate\n",
"from langchain.tools.render import format_tool_to_openai_function\n",
"from langchain_core.messages import BaseMessage, FunctionMessage\n",
"from langchain_core.pydantic_v1 import BaseModel, Field\n",
"from langchain_openai import ChatOpenAI\n",
"from langgraph.prebuilt import ToolInvocation\n",
"\n",
"### Edges\n",
"\n",
"\n",
"def should_retrieve(state):\n",
" \"\"\"\n",
" Decides whether the agent should retrieve more information or end the process.\n",
"\n",
" This function checks the last message in the state for a function call. If a function call is\n",
" present, the process continues to retrieve information. Otherwise, it ends the process.\n",
"\n",
" Args:\n",
" state (messages): The current state of the agent, including all messages.\n",
"\n",
" Returns:\n",
" str: A decision to either \"continue\" the retrieval process or \"end\" it.\n",
" \"\"\"\n",
" print(\"---DECIDE TO RETRIEVE---\")\n",
" messages = state[\"messages\"]\n",
" last_message = messages[-1]\n",
" # If there is no function call, then we finish\n",
" if \"function_call\" not in last_message.additional_kwargs:\n",
" print(\"---DECISION: DO NOT RETRIEVE / DONE---\")\n",
" return \"end\"\n",
" # Otherwise there is a function call, so we continue\n",
" else:\n",
" print(\"---DECISION: RETRIEVE---\")\n",
" return \"continue\"\n",
"\n",
"\n",
"def check_relevance(state):\n",
" \"\"\"\n",
" Determines whether the Agent should continue based on the relevance of retrieved documents.\n",
"\n",
" This function checks if the last message in the conversation is of type FunctionMessage, indicating\n",
" that document retrieval has been performed. It then evaluates the relevance of these documents to the user's\n",
" initial question using a predefined model and output parser. If the documents are relevant, the conversation\n",
" is considered complete. Otherwise, the retrieval process is continued.\n",
"\n",
" Args:\n",
" state messages: The current state of the conversation, including all messages.\n",
"\n",
" Returns:\n",
" str: A directive to either \"end\" the conversation if relevant documents are found, or \"continue\" the retrieval process.\n",
" \"\"\"\n",
"\n",
" print(\"---CHECK RELEVANCE---\")\n",
"\n",
" # Output\n",
" class FunctionOutput(BaseModel):\n",
" binary_score: str = Field(description=\"Relevance score 'yes' or 'no'\")\n",
"\n",
" # Create an instance of the PydanticOutputParser\n",
" parser = PydanticOutputParser(pydantic_object=FunctionOutput)\n",
"\n",
" # Get the format instructions from the output parser\n",
" format_instructions = parser.get_format_instructions()\n",
"\n",
" # Create a prompt template with format instructions and the query\n",
" prompt = PromptTemplate(\n",
" template=\"\"\"You are a grader assessing relevance of retrieved docs to a user question. \\n \n",
" Here are the retrieved docs:\n",
" \\n ------- \\n\n",
" {context} \n",
" \\n ------- \\n\n",
" Here is the user question: {question}\n",
" If the docs contain keyword(s) in the user question, then score them as relevant. \\n\n",
" Give a binary score 'yes' or 'no' score to indicate whether the docs are relevant to the question. \\n \n",
" Output format instructions: \\n {format_instructions}\"\"\",\n",
" input_variables=[\"question\"],\n",
" partial_variables={\"format_instructions\": format_instructions},\n",
" )\n",
"\n",
" model = ChatOpenAI(temperature=0, model=\"gpt-4-0125-preview\")\n",
"\n",
" chain = prompt | model | parser\n",
"\n",
" messages = state[\"messages\"]\n",
" last_message = messages[-1]\n",
" score = chain.invoke(\n",
" {\"question\": messages[0].content, \"context\": last_message.content}\n",
" )\n",
"\n",
" # If relevant\n",
" if score.binary_score == \"yes\":\n",
" print(\"---DECISION: DOCS RELEVANT---\")\n",
" return \"yes\"\n",
"\n",
" else:\n",
" print(\"---DECISION: DOCS NOT RELEVANT---\")\n",
" print(score.binary_score)\n",
" return \"no\"\n",
"\n",
"\n",
"### Nodes\n",
"\n",
"\n",
"# Define the function that calls the model\n",
"def call_model(state):\n",
" \"\"\"\n",
" Invokes the agent model to generate a response based on the current state.\n",
"\n",
" This function calls the agent model to generate a response to the current conversation state.\n",
" The response is added to the state's messages.\n",
"\n",
" Args:\n",
" state (messages): The current state of the agent, including all messages.\n",
"\n",
" Returns:\n",
" dict: The updated state with the new message added to the list of messages.\n",
" \"\"\"\n",
" print(\"---CALL AGENT---\")\n",
" messages = state[\"messages\"]\n",
" model = ChatOpenAI(temperature=0, streaming=True, model=\"gpt-4-0125-preview\")\n",
" functions = [format_tool_to_openai_function(t) for t in tools]\n",
" model = model.bind_functions(functions)\n",
" response = model.invoke(messages)\n",
" # We return a list, because this will get added to the existing list\n",
" return {\"messages\": [response]}\n",
"\n",
"\n",
"# Define the function to execute tools\n",
"def call_tool(state):\n",
" \"\"\"\n",
" Executes a tool based on the last message's function call.\n",
"\n",
" This function is responsible for executing a tool invocation based on the function call\n",
" specified in the last message. The result from the tool execution is added to the conversation\n",
" state as a new message.\n",
"\n",
" Args:\n",
" state (messages): The current state of the agent, including all messages.\n",
"\n",
" Returns:\n",
" dict: The updated state with the new function message added to the list of messages.\n",
" \"\"\"\n",
" print(\"---EXECUTE RETRIEVAL---\")\n",
" messages = state[\"messages\"]\n",
" # Based on the continue condition\n",
" # we know the last message involves a function call\n",
" last_message = messages[-1]\n",
" # We construct an ToolInvocation from the function_call\n",
" action = ToolInvocation(\n",
" tool=last_message.additional_kwargs[\"function_call\"][\"name\"],\n",
" tool_input=json.loads(\n",
" last_message.additional_kwargs[\"function_call\"][\"arguments\"]\n",
" ),\n",
" )\n",
" # We call the tool_executor and get back a response\n",
" response = tool_executor.invoke(action)\n",
" # print(type(response))\n",
" # We use the response to create a FunctionMessage\n",
" function_message = FunctionMessage(content=str(response), name=action.tool)\n",
"\n",
" # We return a list, because this will get added to the existing list\n",
" return {\"messages\": [function_message]}"
]
},
{
"cell_type": "markdown",
"id": "955882ef-7467-48db-ae51-de441f2fc3a7",
"metadata": {},
"source": [
"## Graph\n",
"\n",
"* Start with an agent, `call_model`\n",
"* Agent make a decision to call a function\n",
"* If so, then `action` to call tool (retriever)\n",
"* Then call agent with the tool output added to messages (`state`)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "8718a37f-83c2-4f16-9850-e61e0f49c3d4",
"metadata": {},
"outputs": [],
"source": [
"from langgraph.graph import END, StateGraph\n",
"\n",
"# Define a new graph\n",
"workflow = StateGraph(AgentState)\n",
"\n",
"# Define the nodes we will cycle between\n",
"workflow.add_node(\"agent\", call_model) # agent\n",
"workflow.add_node(\"action\", call_tool) # retrieval"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "b2158218-b21f-491b-853c-876c1afe9ba6",
"metadata": {},
"outputs": [],
"source": [
"# Call agent node to decide to retrieve or not\n",
"workflow.set_entry_point(\"agent\")\n",
"\n",
"# Decide whether to retrieve\n",
"workflow.add_conditional_edges(\n",
" \"agent\",\n",
" # Assess agent decision\n",
" should_retrieve,\n",
" {\n",
" # Call tool node\n",
" \"continue\": \"action\",\n",
" \"end\": END,\n",
" },\n",
")\n",
"\n",
"# Edges taken after the `action` node is called.\n",
"workflow.add_conditional_edges(\n",
" \"action\",\n",
" # Assess agent decision\n",
" check_relevance,\n",
" {\n",
" # Call agent node\n",
" \"yes\": \"agent\",\n",
" \"no\": END, # placeholder\n",
" },\n",
")\n",
"\n",
"# Compile\n",
"app = workflow.compile()"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "7649f05a-cb67-490d-b24a-74d41895139a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---CALL AGENT---\n",
"\"Output from node 'agent':\"\n",
"'---'\n",
"{ 'messages': [ AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"types of agent memory Lilian Weng\"}', 'name': 'retrieve_blog_posts'}})]}\n",
"'\\n---\\n'\n",
"---DECIDE TO RETRIEVE---\n",
"---DECISION: RETRIEVE---\n",
"---EXECUTE RETRIEVAL---\n",
"\"Output from node 'action':\"\n",
"'---'\n",
"{ 'messages': [ FunctionMessage(content='Citation#\\nCited as:\\n\\nWeng, Lilian. (Jun 2023). LLM-powered Autonomous Agents\". LilLog. https://lilianweng.github.io/posts/2023-06-23-agent/.\\n\\nLLM Powered Autonomous Agents\\n \\nDate: June 23, 2023 | Estimated Reading Time: 31 min | Author: Lilian Weng\\n\\n\\n \\n\\n\\nTable of Contents\\n\\n\\n\\nAgent System Overview\\n\\nComponent One: Planning\\n\\nTask Decomposition\\n\\nSelf-Reflection\\n\\n\\nComponent Two: Memory\\n\\nTypes of Memory\\n\\nMaximum Inner Product Search (MIPS)\\n\\nThe design of generative agents combines LLM with memory, planning and reflection mechanisms to enable agents to behave conditioned on past experience, as well as to interact with other agents.\\n\\nWeng, Lilian. (Mar 2023). Prompt Engineering. LilLog. https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/.', name='retrieve_blog_posts')]}\n",
"'\\n---\\n'\n",
"---CHECK RELEVANCE---\n",
"---DECISION: DOCS RELEVANT---\n",
"---CALL AGENT---\n",
"\"Output from node 'agent':\"\n",
"'---'\n",
"{ 'messages': [ AIMessage(content='Lilian Weng\\'s blog post titled \"LLM-powered Autonomous Agents\" discusses the concept of agent memory but does not provide a detailed list of the types of agent memory directly in the provided excerpt. For more detailed information on the types of agent memory, it would be necessary to refer directly to the blog post itself. You can find the post [here](https://lilianweng.github.io/posts/2023-06-23-agent/).')]}\n",
"'\\n---\\n'\n",
"---DECIDE TO RETRIEVE---\n",
"---DECISION: DO NOT RETRIEVE / DONE---\n",
"\"Output from node '__end__':\"\n",
"'---'\n",
"{ 'messages': [ HumanMessage(content=\"What are the types of agent memory based on Lilian Weng's blog post?\"),\n",
" AIMessage(content='', additional_kwargs={'function_call': {'arguments': '{\"query\":\"types of agent memory Lilian Weng\"}', 'name': 'retrieve_blog_posts'}}),\n",
" FunctionMessage(content='Citation#\\nCited as:\\n\\nWeng, Lilian. (Jun 2023). LLM-powered Autonomous Agents\". LilLog. https://lilianweng.github.io/posts/2023-06-23-agent/.\\n\\nLLM Powered Autonomous Agents\\n \\nDate: June 23, 2023 | Estimated Reading Time: 31 min | Author: Lilian Weng\\n\\n\\n \\n\\n\\nTable of Contents\\n\\n\\n\\nAgent System Overview\\n\\nComponent One: Planning\\n\\nTask Decomposition\\n\\nSelf-Reflection\\n\\n\\nComponent Two: Memory\\n\\nTypes of Memory\\n\\nMaximum Inner Product Search (MIPS)\\n\\nThe design of generative agents combines LLM with memory, planning and reflection mechanisms to enable agents to behave conditioned on past experience, as well as to interact with other agents.\\n\\nWeng, Lilian. (Mar 2023). Prompt Engineering. LilLog. https://lilianweng.github.io/posts/2023-03-15-prompt-engineering/.', name='retrieve_blog_posts'),\n",
" AIMessage(content='Lilian Weng\\'s blog post titled \"LLM-powered Autonomous Agents\" discusses the concept of agent memory but does not provide a detailed list of the types of agent memory directly in the provided excerpt. For more detailed information on the types of agent memory, it would be necessary to refer directly to the blog post itself. You can find the post [here](https://lilianweng.github.io/posts/2023-06-23-agent/).')]}\n",
"'\\n---\\n'\n"
]
}
],
"source": [
"import pprint\n",
"\n",
"from langchain_core.messages import HumanMessage\n",
"\n",
"inputs = {\n",
" \"messages\": [\n",
" HumanMessage(\n",
" content=\"What are the types of agent memory based on Lilian Weng's blog post?\"\n",
" )\n",
" ]\n",
"}\n",
"for output in app.stream(inputs):\n",
" for key, value in output.items():\n",
" pprint.pprint(f\"Output from node '{key}':\")\n",
" pprint.pprint(\"---\")\n",
" pprint.pprint(value, indent=2, width=80, depth=None)\n",
" pprint.pprint(\"\\n---\\n\")"
]
},
{
"cell_type": "markdown",
"id": "93781e8c-dd25-4754-9c26-e5faac57e715",
"metadata": {},
"source": [
"Trace:\n",
"\n",
"https://smith.langchain.com/public/6f45c61b-69a0-4b35-bab9-679a8840a2d6/r"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "189333cc-5d34-4869-9f9b-741210e1096f",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
}
},
"nbformat": 4,
"nbformat_minor": 5
}