{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/home/teddy/miniconda3/envs/gsnn-lib/lib/python3.12/site-packages/torch_geometric/typing.py:124: UserWarning: An issue occurred while importing 'torch-sparse'. Disabling its usage. Stacktrace: /home/teddy/miniconda3/envs/gsnn-lib/lib/python3.12/site-packages/torch_sparse/_version_cuda.so: undefined symbol: _ZN5torch3jit17parseSchemaOrNameERKSs\n", " warnings.warn(f\"An issue occurred while importing 'torch-sparse'. \"\n" ] } ], "source": [ "from gsnn.models.GSNN import GSNN\n", "from gsnn.simulate.nx2pyg import nx2pyg \n", "\n", "import networkx as nx \n", "import torch \n", "from torch_geometric.data import HeteroData\n", "from matplotlib import pyplot as plt\n", "import matplotlib.patches as patches\n", "\n", "%load_ext autoreload\n", "%autoreload 2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# General Premise\n", "\n", "The GSNN method is a way of including prior knowledge of variable interactions directly into neural architecture. Prior knowledge is specified using a Pytorch Geometric `HeteroData` object. The minimal requirements of this are: \n", "\n", "```python \n", "import torch_geometric as pyg \n", "\n", "data = pyg.data.HeteroData() \n", "\n", "data.edge_index_dict = {('input', 'to', 'function'):input_edge_index, \n", "\t\t\t\t\t\t('function', 'to', 'function'): function_edge_index, \n", "\t\t\t\t\t\t('function','to','output'):output_edge_index}\n", "\n", "data.node_names_dict = {'input':input_names,\n", "\t\t\t\t\t\t'function':function_names,\n", "\t\t\t\t\t\t'output':output_names}\n", "\n", "```\n", "\n", "The edge indexes should be a torch LongTensor and the node names should be ordered respective to node indexing represented in the edge indicies. " ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAGFCAYAAABg2vAPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAfQUlEQVR4nO3de3SU5aHv8d87M0nIHSYXEM0YSQKUiMUlKRxclEYhe8FqI7htg0pWvbG2dnnOklbd1gsXtwtZa9PS7lNt9dTuZst100IP3R45yBIBC6ZRy2lAS8JCM5RLLhPJTC4OmZn3/EGJpBAIcZIh83w/f5F5b8+w1pv55p1n5rVs27YFAACM5Yj1AAAAQGwRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADOfqz0qRSEQnTpxQenq6LMsa7DEBAIAosG1bgUBAY8eOlcPR99///YqBEydOKC8vL2qDAwAAQ+fYsWO67rrr+lzerxhIT0/v2VlGRkZ0RgYAAAaV3+9XXl5ez+t4X/oVA+feGsjIyCAGAAAYZi73Fj8TCAEAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhnPFegAAYqcjGNKnvg6dCUWU6HIoPytVqUn8WgBMw1kPGKa+MaB11V7tOtwkb2un7POWWZI87hSVTsjVvdM8KhqdHqthAhhClm3b9uVW8vv9yszMVFtbmzIyMoZiXACi7Fhrp57eWqu9R1rkdFgKR/o+9c8tn1mYrZULJivPnTKEIwUQLf19/WbOAGCAjTVezV6zW/uO+iTpkiFw/vJ9R32avWa3NtZ4B32MAGKHtwmAOPezXfVavaNuQNuGI7bCEVtPbalVS3tQj5YWRXl0AK4GXBkA4tjGGu+AQ+Dvrd5Rp01cIQDiEjEAxKljrZ1atu1QVPe5dNshHWvtjOo+AcQeMQDEqYrHX1TdC/MUOt04oO397/9ex199WA3/Ol9//fmDOv3uenV3d+vprbVRHimAWGPOABCH6hsDOpb+FY2pXC1nmvuKt2/bt0mn96xVxn+7S8n5Nyt4ql6n97yucMCnvdZ/15GmgApz+dghEC+4MgDEoXXVXiWmjVTStRNluRKuaNtwl19t+zYpbco/aNSs72rE9Tcpc9o/auSt96j9/+1Q2HdMa99j7gAQT4gBIA7tOtyktgNvqWHVN3veJji17imd+OX3FDxZp1Nrn5R39T/q+M8fVNv+zbLtSM+2XUc/kB06o7TJs3vtM/Wm2ZJstR/er111TUP5dAAMMmIAiDPtwZC8fUzyC3ecVsu21UotLlXOXc9pRMFUnd5dpY6Du3rW6W5ukCQl5OT32taV5pYjOUNnWhrk9XWqIxgatOcAYGgRA0CcafB1qK+vFIp0+ZX9rR8o/ea5Ss6foqyyR5SQ7VHHR7vPWycgORPkSBxxwfaO5HRFuvyyJX3q6xicJwBgyBEDQJw5E4r0ucyZOkpJYyf0eiwhJ18hf+/L/pZlXeII1mWPA2B4IQaAOJPo6vu0diRf+AkAy5kgu/tMr3Xs0BlFuj+/YN1IV6BnH5c6DoDhhbMZiDP5Wam61N/1l5P4t7kC5+YOnBNu/0yRLr8Ss6+X9bfjAIgPxAAQZ1KTXPJ8ibsMjhh3iyxXotprd/Z6/OzPlpLHT5cnK0WpSXxNCRAvOJuBOFQ6IVcf7xnYts7kdGXOqNDpPWvlGJGu5BtuVvBkvU6/u15pXy1Tcu71Kh2fG90BA4gpYgCIQ/dO8+hnrwx8+8wZFbISkxX48A35/7hFztRRypx+lzJnVCgcsbVouid6gwUQc5Zt25e+sbkkv9+vzMxMtbW1KSMjYyjGBeBLqnytWvuO+hSOXPYU7zenw9KMcVl6/cFpUdsngMHT39dv5gwAcWrlgslyOb7MVMILuRyWVi6YHNV9Aog9YgCIU3nuFK0oL47qPp8vL1bel5icCODqRAwAcWxhiUePl42Pyr6eKJugihLmCgDxiAmEQJx7tLRI2WlJWrbtkEIR+4rmEDgdllwOS8+XFxMCQBzjygBggIUlHu1cMkszxmVJOvsifynnls8Yl6WdS2YRAkCc48oAYIg8d4pef3Ca6hsDWlft1a66Jnl9nb1uamRJ8mSlqHR8rhZN96gw98KvLwYQf/hoIWCwjmBI8ysXy7ac+umaHyk/K5VvFgTiSH9fvznrAYOlJrmU/LlPklQ8NjPGowEQK8wZAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMJwr1gMAMPS8Xq9+/vOfKxwO66OPPpIkPfnkk3I6nXrkkUfk8XhiPEIAQ4kYAAxUU1OjVatWyel0KhKJSJJ+/OMfKxwOa+rUqcQAYBjeJgAMVF5erry8PEUiEdm2Ldu2FYlE5PF4VF5eHuvhARhixABgoISEBC1fvly2bfc8Ztu2li9froSEhBiODEAsEAOAoSorK5WXl9fzs8fj0aJFi2I4IgCxQgwAhjp3deAcrgoA5rLs868T9sHv9yszM1NtbW3KyMgYinEBGALd3d3KzMyUJLW1tREDQJzp7+s3nyYADHYmYuml9f9bIdtSXXOn8rNSlZrErwXANJz1gGHqGwNaV+3VrsNN8rZ2qufS4B/flSXJ405R6YRc3TvNo6LR6TEcKYChwtsEgCGOtXbq6a212nukRU6HpXCk71P/3PKZhdlauWCy8twpQzhSANHS39dvJhACBthY49XsNbu176hPki4ZAucv33fUp9lrdmtjjXfQxwggdnibAIhzP9tVr9U76ga0bThiKxyx9dSWWrW0B/VoaVGURwfgasCVASCObazxDjgE/t7qHXXaxBUCIC4RA8Aws2nTJhUXFys5OVmWZenAgQMXXe9Ya6eWbTsU1WMv3XZIx1o7e35ub2/XY489prFjx2rEiBGaMmWKNm7cGNVjAhh8xAAwjDQ3N6uyslIFBQXavn279u/fr/Hjx1903ae31ip0mbkBVyoUsfX01tqen++8805VVVVp2bJlevPNN1VSUqK7775b69evj+pxAQwu5gwAw0hdXZ26u7u1aNEizZo1q8/16hsD2nukJerHD0ds7T3SoiNNAdW9v1dvvfWW1q9fr7vvvluSVFpaqoaGBj3xxBOqqKiQ0+mM+hgARB8xAAwT9913n6qqqiRJFRUVqqio6BUE77zzTs+/11V75XtjjboaanXd934lSQqdbtTxXzyokaUPyLIs+T/4L0U625SQc73cty9W0rUTex0veOKw2v6wUcHjf1Gk+3O50rOUXPg15ZT9k9a+59Xx329VWlqavv3tb/fa7v7779c999yj6upqzZgxY5D+NwBEE28TAMPEc889p5deekmStHLlSu3fv18vv/zyRdfddbhJfX2DSODDN9T16QG5b1+s7G89Lrs7qKbNyxX5vKNnna6jH+jU2n9WyN+sUbc/pNHfWaHMGRUKd5xWOGJrV12TDh48qK985StyuXr/TXHTTTdJkg4ePBiFZw1gKHBlABgmCgoKNGnSJElSUVGRpk+fftH12oMhec+b5Pf3HInJyr1rqSzH2Uv4znS3TlV9X11H31fqpLNXGlp3/EKujBxd890fy3Il9mybdtMcSZLX1ylXi08FBeMu2L/b7ZYk+Xy+ATxLALHAlQEgzjT4OnSpaYPJBVN7QkCSEnNukCSF/M2SpO7W4wqdPqm0r87pFQLnsyV1hyOyLKvP41xqGYCrCzEAxJkzocgllzuSe38lqeU6e6dCuzsoSQp3tkmSnOnZl9xPxshRF/3rv7W1VdIXVwgAXP2IAWCYGzFihILBYM/Pia6zp3Wkyz+g/TlTzt7SOBy49KcRJkwq1scff6xQKNTr8drasx89vPHGGwd0fABDjxgAhrn8/HzV1dX1BEF+VqoiXX4Fj388oP0luK+Va+Q1av/zW7JD3Rddx5J0z3fuUnt7u37729/2WlZVVaWxY8dq2rRpAzo+gKHHBEJgmKusrNQrr7yiRYsWafHixfL5fGrdvFRW4sDvNOgue1hNv/kXnfyPHyij5A65MnIU8jer65MPlVP+hDxZKVpQXqo5c+bokUcekd/vV2FhoTZs2KDt27dr7dq1fMcAMIwQA8Awd+utt6qqqkqrVq3SHXfcoXHjxmnuvQ9r+/Y31dVQe/kdXETyuFs05t5VOv2HDWrd+ars0Bm50rOVXPQ1OR2WSsfnSpK2bNmiZ555RkuXLlVra6smTpyoDRs2aOHChdF8igAGmWXbfX0a+Qv9vR8ygKtDfWNAc36yZ9D2v3PJ11WYmz5o+wcQHf19/WbOABCHikana2ZhtpyO6H68z+mwNLMwmxAA4gwxAMSplQsmyxXlGHA5LK1cMDmq+wQQe8QAEKfy3ClaUV4c1X0+X16sPPfAJyYCuDoRA0AcW1ji0eNlF7/F8ZV6omyCKko8UdkXgKsLnyYA4tyjpUXKTkvSsm2HFIrYCkcuO2e4h9NhyeWw9Hx5MSEAxDGuDAAGWFji0c4lszRjXJYkXXZi4bnlM8ZlaeeSWYQAEOe4MgAYIs+dotcfnKb6xoDWVXu1q65JXl9nr5saWZI8WSkqHZ+rRdM9fGoAMATfMwAYrCMY0vzKxbItp3665kfKz0pVahJ/IwDxor+v35z1gMFSk1xK/vzsnQeLx2bGeDQAYoU5AwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIZzxXoAAIbegQMH9MMf/lDhcFh/+tOfJEllZWVyOp168cUXNWXKlNgOEMCQIgYAAzU1NWn79u29HnvrrbckSd///vdjMSQAMcTbBICB5syZoylTpsjpdPY85nQ6dfPNN2v27NkxHBmAWCAGAANZlqUXXnhB4XC457FwOKwXXnhBlmXFcGQAYoEYAAw1b968XnMDbr75Zs2dOzd2AwIQM8QAYKhzVwfO4aoAYC7Ltm37civ5/X5lZmaqra1NGRkZQzEuAEPAtm3l5ORIkpqbm4kBIM709/WbTxMABus8E9Zv365Wd9jWRyf9ys9KVWoSvxYA03DWA4apbwxoXbVXuw43ydvaqS8uDR6WJcnjTlHphFzdO82jotHpsRsogCHD2wSAIY61durprbXae6RFToelcKTvU//c8pmF2Vq5YLLy3ClDOFIA0dLf128mEAIG2Fjj1ew1u7XvqE+SLhkC5y/fd9Sn2Wt2a2ONd9DHCCB2eJsAiHM/21Wv1TvqBrRtOGIrHLH11JZatbQH9WhpUZRHB+BqwJUBII5trPEOOAT+3uodddrEFQIgLhEDwDCzadMmFRcXKzk5WZZl6cCBAxdd71hrp5ZtOxTVYy/ddkjHWjslSYFAQE8++aTKysqUk5Mjy7K0fPnyqB4PwNAgBoBhpLm5WZWVlSooKND27du1f/9+jR8//qLrPr21VqHLzA24UqGIrae31kqSfD6fXn31VQWDQc2fPz+qxwEwtJgzAAwjdXV16u7u1qJFizRr1qw+16tvDGjvkZaoHz8csbX3SIuONAVUcP31+uyzz2RZllpaWvTLX/4y6scDMDSIAWCYuO+++1RVVSVJqqioUEVFRa8geOedd3r+va7aK98ba9TVUKvrvvcrSVLodKOO/+JBjSx9QJZlyf/BfynS2aaEnOvlvn2xkq6d2Ot4wROH1faHjQoe/4si3Z/LlZ6l5MKvKafsn7T2Pa+WlxcP/pMGMCR4mwAYJp577jm99NJLkqSVK1dq//79evnlly+67q7DTerrG0QCH76hrk8PyH37YmV/63HZ3UE1bV6uyOcdPet0Hf1Ap9b+s0L+Zo26/SGN/s4KZc6oULjjtMIRW7vqmqL+/ADEDlcGgGGioKBAkyZNkiQVFRVp+vTpF12vPRiS92+T/C7GkZis3LuWynI4JUnOdLdOVX1fXUffV+qks1caWnf8Qq6MHF3z3R/LciX2bJt20xxJktfXqY5giK8uBuIEVwaAONPg69Clpg0mF0ztCQFJSsy5QZIU8jdLkrpbjyt0+qTSvjqnVwicz5b0qa/jossADD/EABBnzoQil1zuSO79laSWK0GSZHcHJUnhzjZJkjM9+0sdB8DwQQwAw9yIESMUDAZ7fk50nT2tI13+Ae3PmZIpSQoHLv1phHPHATD8cTYDw1x+fr7q6up6giA/K1WRLr+Cxz8e0P4S3NfKNfIatf/5Ldmh7ouuY/3tOADiA7N/gGGusrJSr7zyihYtWqTFixfL5/OpdfNSWYkDv9Ogu+xhNf3mX3TyP36gjJI75MrIUcjfrK5PPlRO+RPyZKUoNcmlN998Ux0dHQoEApKkjz76SL/5zW8kSfPmzVNKCnc7BIYDYgAY5m699VZVVVVp1apVuuOOOzRu3DjNvfdhbd/+proaage0z+Rxt2jMvat0+g8b1LrzVdmhM3KlZyu56GtyOiyVjs+VJD3yyCNqaGjo2W7z5s3avHmzJOmTTz5Rfn7+l35+AAafZdt9fRr5C/29HzKAq0N9Y0BzfrJn0Pa/c8nXVZibPmj7BxAd/X39Zs4AEIeKRqdrZmG2nA4rqvt1OizNLMwmBIA4QwwAcWrlgslyRTkGXA5LKxdMjuo+AcQeMQDEqTx3ilZE+f4Bz5cXK8/NpEAg3hADQBxbWOLR42UXv8XxlXqibIIqSjxR2ReAqwufJgDi3KOlRcpOS9KybYcUitgKRy47Z7iH02HJ5bD0fHkxIQDEMa4MAAZYWOLRziWzNGNcliRddmLhueUzxmVp55JZhAAQ57gyABgiz52i1x+cpvrGgNZVe7WrrkleX2evmxpZkjxZKSodn6tF0z18agAwBN8zABisIxjS/MrFsi2nfrrmR8rPSuW2xEAc6e/rN2c9YLDUJJeSP/dJkorHZsZ4NABihTkDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4YgBAAAMRwwAAGA4YgAAAMMRAwAAGI4YAADAcMQAAACGIwYAADAcMQAAgOGIAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhnPFegAAht7bb7+te+65R6FQSH6/X5KUnZ0tl8ul9evX67bbbovxCAEMJWIAMFBGRoYaGxt7Pebz+SRJmZmZsRgSgBjibQLAQFOnTtXcuXPldDp7HnM6nZo3b55uueWWGI4MQCwQA4ChVqxYoXA43PNzOBzWihUrYjgiALFCDACGKikp0dy5c2VZlizL0rx58zR16tRYDwtADBADgMFWrFgh27Zl2zZXBQCDMYEQMFhJSYnGjx8vy7K4KgAYjBgADNYRDGnL239UMBzRoRNtys9KVWoSvxYA03DWA4apbwxoXbVXuw43ydvaKfu8ZZYkjztFpRNyde80j4pGp8dqmACGkGXbtn25lfx+vzIzM9XW1qaMjIyhGBeAKDvW2qmnt9Zq75EWOR2WwpG+T/1zy2cWZmvlgsnKc6cM4UgBREt/X7+ZQAgYYGONV7PX7Na+o2e/WOhSIXD+8n1HfZq9Zrc21ngHfYwAYoe3CYA497Nd9Vq9o25A24YjtsIRW09tqVVLe1CPlhZFeXQArgZcGQDi2MYa74BD4O+t3lGnTVwhAOISMQDEqWOtnVq27dAVbxf48A21/3nnRZct3XZIz6/6kSZOnKikpCTdcMMNWrFihbq7u7/scAHEEG8TAHHq6a21Cl1mbsDFBD58Q47kDKXdNPuCZc17N2jZnrX64VNPqaysTDU1NXr22Wd1/Phxvfrqq9EYNoAYIAaAOFTfGNDeIy1R3We4y6/Tf9iktK/+gx547IcqzE3XN77xDXV3d+vZZ5/VY489pkmTJkX1mACGBm8TAHHg3Xff1e2336709HSlpKTotlkzFTxa07P89N51alj1zQu2a//zTjWs+qZCp8/ezvivLz+g7havgscOqmHVN9Ww6pv668sPSJK6jn4gO3RGGV+do7XvfTF34P7775dt2/rd7343uE8SwKAhBoBhbvfu3brtttvU1tam1157TRs2bFCHnaBT//m8Oj7ec0X7yr3zGblGjlHi6AKNqVytMZWrlXvnM5Kk7uYGSZIz63rtqmvq2eaaa65Rdna2Dh48GL0nBWBI8TYBMMw99dRTGjVqlN555x2lpaWpPRhSxj5L7f/+P/TZ279SysSZ/d5X4pgCWa5EWYnJSrp2Yq9lka6A5EyQI3GEvL5OdQRDPV9d7Ha75fP5ovq8AAwdrgwAw1hHR4eqq6t11113KS0tTZLU4OuQHE6lFpcqHGhRqPWvUTueZVmSJFvSp76Oiy4DMPwQA8Aw9tlnn8m2bV1zzTU9j50JRSRJzrQsSVK4KxCVYzmS02WHzijS/Xmv40hSa2ur3G53VI4DYOgRA8AwNmrUKDkcDp08ebLnsUTX2dM63H72sr0zOUOWK1GSZId6fx9AuMvf72Ml5uRL+mLuwLnjnDp1Si0tLbrxxhsH9iQAxBwxAAxjqampmjZtmrZs2aKuri5JUn5WqmRH1HHoHTnTs+VyXytXZq4k6UzzJ7227zryxwv2aTkTZIfOXPD4iHG3yHIlqr12p6xzx5H061//WpZlaf78+dF9cgCGDBMIgWHuxRdf1Jw5c1RaWqrHH39ciYmJ8m99Qd3NDcq+4wlZlqXkghI5RqTL93/+TSNn3is5nOqo3amwv/mC/SXk5Kvj4z3q+HiPXCPHyHImKjE3X87kdGXOqNDpPWs1apRb77+XppqaGi1fvlwPPfQQ3zEADGPcwhiIA++++66WLVum6upqRSIRZXnGq/um+RpRUNKzTvBknT7b+b90pukTOUakKu2mMjkzctT65r/p2odfk2vkaElSqK1Jvu3/U8Hjf5F9pkvOjFxd971f9eyn/YPfS4f+rwItJzRmzBjdf//9euaZZ5SQkDDkzxvApfX39ZsYAOJQfWNAc35yZd8xcCV2Lvm6CnPTB23/AKKjv6/fzBkA4lDR6HTNLMyW0xHdj/s5HZZmFmYTAkCcIQaAOLVywWS5ohwDLoellQsmR3WfAGKPGADiVJ47RSvKi6O6z+fLi5XnTonqPgHEHjEAxLGFJR49XjY+Kvt6omyCKko8UdkXgKsLHy0E4tyjpUXKTkvSsm2HFIrYCkcuO2e4h9NhyeWw9Hx5MSEAxDGuDAAGWFji0c4lszRj3NmvKL7cxMJzy2eMy9LOJbMIASDOcWUAMESeO0WvPzhN9Y0Brav2alddk7y+Tp1/ncCS5MlKUen4XC2a7uFTA4Ah+J4BwGAdwZA+9XXoTCiiRJdD+VmpPbclBjD89ff1m7MeMFhqkkvFYzNjPQwAMcacAQAADEcMAABgOGIAAADDEQMAABiOGAAAwHDEAAAAhiMGAAAwHDEAAIDhiAEAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMBwxAACA4Vz9Wcm2bUmS3+8f1MEAAIDoOfe6fe51vC/9ioFAICBJysvL+5LDAgAAQy0QCCgzM7PP5ZZ9uVyQFIlEdOLECaWnp8uyrKgOEAAADA7bthUIBDR27Fg5HH3PDOhXDAAAgPjFBEIAAAxHDAAAYDhiAAAAwxEDAAAYjhgAAMBwxAAAAIYjBgAAMNz/B36TuzGLM52JAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "G = nx.DiGraph([('in0','func0'), ('func0', 'func1'), ('func1', 'out0')])\n", "nx.draw_networkx(G, pos={'in0':(0,0), 'func0': (0,-1), 'func1':(0,-2), 'out0':(0,-3)})" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "HeteroData(\n", " edge_index_dict={\n", " (input, to, function)=[2, 1],\n", " (function, to, function)=[2, 1],\n", " (function, to, output)=[2, 1],\n", " },\n", " node_names_dict={\n", " input=[1],\n", " function=[2],\n", " output=[1],\n", " }\n", ")" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "data = nx2pyg(G, ['in0'], ['func0', 'func1'], ['out0'])\n", "data" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# create some dummy data \n", "x = torch.randn((10,len(data.node_names_dict['input'])))" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "model = GSNN(edge_index_dict=data.edge_index_dict, \n", " node_names_dict=data.node_names_dict, \n", " channels = 3, \n", " layers = 4)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[0.0112],\n", " [0.0086],\n", " [0.0117],\n", " [0.0474],\n", " [0.0446],\n", " [0.0111],\n", " [0.0116],\n", " [0.0352],\n", " [0.0112],\n", " [0.0116]], grad_fn=)" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# note that the output has size (Batch, num_outputs)\n", "model(x)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "ResBlock(\n", " (lin1): SparseLinear(\n", " (conv): Conv()\n", " )\n", " (norm1): GroupLayerNorm()\n", " (lin3): SparseLinear(\n", " (conv): Conv()\n", " )\n", " (nonlin): GELU(approximate='none')\n", ")" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model.ResBlocks[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## What is happening under the GSNN hood? \n", "\n", "In the plot below, we show the resulting internal structure of the GSNN. \n", "\n", "The \"E1\" node represents the input from node \"in0\"\n", "\n", "Each edge in the graph below represents a trainable edge weight randomly initialized. \n", "\n", "The \"NNx\" nodes represent layer normalization and non-linearity operations (within gray bounding boxes). \n", "\n", "The \"E0\" node represents a latent channel in the layer. \n", "\n", "The \"E2\" node represents the predicted output and will be the resulting value output to the \"out0\" node. " ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAgMAAAGFCAYAAABg2vAPAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAB1sUlEQVR4nO3deXiM5/7H8fdMNksIQkwWQSqW2KLEVlvsW2InCJPi1K4o6qAt1aqipS1dlDYjscRaia222LdorWktQWQd0eQklsg68/ujp/nVUQRJnknyfV1Xr6udmTzzmcY9z8ez3LfKaDQaEUIIIUSxpVY6gBBCCCGUJWVACCGEKOakDAghhBDFnJQBIYQQopiTMiCEEEIUc1IGhBBCiGJOyoAQQghRzJnn5kUGg4G4uDjKlCmDSqXK70xCCCGEyANGo5H79+/j4OCAWv30v//nqgzExcVRpUqVPAsnhBBCiIITHR2Nk5PTU5/PVRkoU6ZMzsbKli2bN8mEEEIIka/u3btHlSpVcvbjT5OrMvDXqYGyZctKGRBCCCEKmeed4pcLCIUQQohiTsqAEEIIUcxJGRBCCCGKOSkDQgghRDEnZUAIIYQo5qQMCCGEEMWclAEhhBCimJMyIIQQQhRzUgaEEEKIYk7KgBBCCFHMSRkQQgghijkpA0IIIUQxJ2VACCGEKOakDAghhBDFnJQBIYQQopiTMiCEEEIUc+ZKBxBCKOdhehaRiQ/JyDJgaa6mmm1pSlvJ14IQxY2MeiGKmet37rP2dBShVxOISkrF+LfnVIBzhVJ41rJjaDNnXCuXUSqmEKIAqYxGo/F5L7p37x42NjakpKRQtmzZgsglhMhj0UmpzNp2iaMRf2CmVpFtePrQ/+v51jUqsqBPfapUKFWASYUQeSW3+2+5ZkCIYmBDWBQdlx7mxM1EgGcWgb8/f+JmIh2XHmZDWFS+ZxRCKEdOEwhRxC0Pvc6Svdde6mezDUayDUZmbr3EHw/SmeDpmsfphBCmQI4MCFGEbQiLeuki8L+W7L1GkBwhEKJIkjIgRBEVnZTKB8HhebrN94PDiU5KzdNtCiGUJ6cJhCiiZm27RJbByIOL+0ncteypr6s8eAElqjYgNeIMqb8fJSPhJpmJMWDIpurMHY+9NstgZNa2SwSMbJbP6YUQBUnKgBBF0PU79zka8cdjj9l2n4yFrdMTr7Wo6AxA6rWTpMddxbLya6jMLMjQRzzx2myDkaMRfxCRcJ8adnLboRBFhZQBIYqgtaejnrh90KJSVazsn34BoG23iahUf545TNr7zT+WAfjztsPAU1HM9a6bt6GFEIqRawaEKIJCryY89/bB//VXEXiebIOR0GsJLxNLCGGipAwIUcQ8SM8i6p8u8jMaMBqyn/jnZUQlpvIwPesVkwohTIWcJhCiiLmd+JB/OiagX/POkw+q1FR9N/iF38MIRCY+pK6DzQv/rBDC9EgZEKKIycgy/OPjtj2nYmFb5fEHVao8fx8hROEjZUCIIsbS/J/P/lnYVnnmBYR59T5CiMJHRrMQRUw129K8/N/3c0f13/cRQhQNUgaEKGJKW5njnM+rDDrblqK0lRxYFKKokNEsRBFhNBo5evQoOp2OiLtlsKrXib/fXZh59zb8w90D5uXtMStlQ1ZKAunxf65jkJmsB+DhlWN/vsamcs4pBqMhm+zoixw9ak6rVq1QvcJ1B0II0yBlQIhC7tatW6xZswadTsetW7eoXr06A3zf4qfMx1/3tCmJK3SbSJmGXUi7ffGJ1/zx00IAStfrgFXPKQCo1GbEHtpAmy8n4+LiwvDhwxk+fDjVq1fP648mhCggKqPR+NyZSe7du4eNjQ0pKSmULVu2IHIJIZ7h/v37bN68GZ1Ox+HDh7G2tmbgwIFotVpatWqFWq1m2OrTnLiZ+MKTDz2LmVpFSxdbdG96cOzYMfz9/dm0aRMPHjygbdu2aLVa+vfvT5kyMlWxEKYgt/tvuWZAiELCYDBw4MABhg8fjkajYeTIkZibmxMQEIBer2f16tW0adMGtfrPYb2gT33M1Xl7CN9crWJBn/qo1WratGnDDz/8gF6vZ82aNZibmzNy5Eg0Gg3Dhw/n4MGDGAxy+6EQhYEcGRDCxF2/fh2dTkdAQABRUVG4urri5+eHr68vzs7Oz/zZDWFRzNx6Kc+yfNq3PoM8nv6eUVFRBAQEoNPpuH79Os7OzgwbNgytVoura97d1iiEyJ3c7r+lDAhhgpKTk9m4cSM6nY4TJ05gY2PDoEGD8PPzo3nz5i900d7y0Oss2XvtlTNN71yL8Z41cvVao9HIyZMn0el0BAUFkZKSQsuWLfHz82PgwIHY2MjMhUIUBCkDQhQy2dnZ7Nu3D51Ox08//URGRgadO3fGz88Pb29vSpYs+dLb3hAWxQfB4WQZjC90DYGZWoW5WsWH3nWfeUTgWR49esT27dvR6XTs3bsXS0tLevfujZ+fHx07dsTMzOyltiuEeD4pA0IUEr/99hs6nY7AwEDi4uJwc3NDq9Xi6+uLg4NDnr1PdFIqs7Zd4mjEH08sb/y//nq+dY2KLOhTnyp5NG9BXFwcgYGB6HQ6fvvtNxwcHHJOI9SpUydP3kMI8f+kDAhhwpKSkli/fj06nY6wsDAqVKjA4MGD8fPzo3Hjxvl67/71O/dZezqK0GsJRCWmPraokYo/JxTyrGmHb3Nnatjlz10BRqORs2fPotPpWLduHf/5z3/w8PDAz88PHx8fKlSokC/vK0RxI2VACBOTmZnJzz//jL+/PyEhIWRnZ9O9e3f8/Pzo0aMHVlZWBZ7pYXoWvYf9C6PKjC+WfkY129IFPrNgeno6O3bsQKfTsWvXLszMzPD29kar1dKlSxcsLCwKNI8QRYmUASFMxIULF9DpdKxdu5aEhAQaNmyIn58fQ4YMwc7OTul4eHt7AxAc/OJLGee1O3fusG7dOnQ6HRcuXMDOzg5fX1+0Wi0NGjRQOp4QhY7MMyCEghISEli2bBmNGjXC3d2dwMBAhgwZwrlz5zh//jyTJ082iSJgaipXrsyUKVM4f/48586dY8iQIQQEBNCwYUNef/11vvjiC+7evat0TCGKHCkDQuSRjIwMtm7dSq9evXB0dGTGjBm4uLgQHBxMbGwsS5cuxd3dXemYhYa7uztLly4lNjaW7du3U716daZPn46DgwO9e/dm27ZtZGRkKB1TiCJByoAQr8BoNPLLL78wceJEHBwc6NevH3FxcSxbtoz4+Hi2bNmCl5eXnPd+BRYWFnh7e7Nlyxbi4+NzCkLfvn1xcHBg0qRJ/PLLL+TijKcQ4imkDAjxEuLj41m8eDH169enSZMmbNmyhREjRnD58mXCwsIYP348tra2SscscmxtbZkwYQJhYWFcvnyZESNGsHnzZpo0aUKDBg1YsmQJ8fHxSscUotCRMiBELqWlpREUFET37t1xcnLivffeo169euzevZuoqCgWLVpE3bp1lY5ZbNStW5dFixYRFRXFrl27qFu3LnPmzMHJyYnu3buzceNG0tLSlI4pRKEgZUCIZzAajZw6dYoxY8Zgb2+Pj48PycnJfP311+j1ejZs2EDXrl0xN5fVwJVibm5Ot27d2LBhA/Hx8Xz99dckJyczaNAg7O3tGTt2LKdOnZLTCEI8g5QBIf5BdHQ0CxYsoHbt2rRo0YJdu3Yxbtw4rly5wokTJxg9ejTlypVTOqb4H+XLl2f06NGcOHGCK1euMG7cOHbs2EGLFi2oU6cOn3zyCTExMUrHFMLkSBkQ4r9SU1NZu3YtnTp1omrVqnz00Uc0bdqU/fv3ExkZyccff0ytWrWUjilyqVatWnz88cdERkayb98+PDw8mD9/Ps7OznTu3Jm1a9eSmpqqdEwhTIKUAVGsGY1Gjhw5wsiRI9FoNPj6+pKRkcHq1au5c+cOAQEBdOjQAbVahkphZWZmRseOHQkICECv17Nq1SrS0tLw9fVFo9EwatQojh49KqcRRLEm33CiWLp16xbz5s2jRo0atG3bltDQUKZOncqNGzc4fPgwb775JmXK5M+8/EI5ZcuWZcSIERw5coQbN24wdepUDhw4QJs2bXB1deXDDz8kMjJS6ZhCFDiZjlgUG/fv32fz5s3odDoOHz6MtbU1AwYMwM/Pj1atWhXbv/2b0nTESjAYDBw9ehR/f382bdrEw4cPadeuHVqtlv79+2Ntba10RCFemkxHLAR/ftEfPHiQ4cOHo9FoGDlyJObm5qxZswa9Xs8PP/xAmzZtim0REKBWq2nbti0//vgjd+7cYc2aNajVakaMGIFGo0Gr1XLw4EEMBoPSUYXIN/INKIqk69evM2fOHKpXr06HDh04deoUs2bNIjIykv379zNs2DBKly6tdExhYkqXLs2wYcM4cOAAkZGR/Pvf/+bEiRN06NCB6tWr89577xEREaF0TCHynJQBUWSkpKTw/fff88Ybb1CzZk2WL19O165dOX78OFevXmX27Nk4OzsrHVMUEs7OzsyePZtr165x/PhxunbtypdffomrqyutWrXi+++/JyUlRemYQuQJKQOiUMvOzubnn39m8ODBaDQaxowZQ9myZVm/fj3x8fF89913tGzZEpVKpXRUUUipVCpatmzJd999h16vZ/369VhbWzNmzBg0Gg1Dhgxh7969ZGdnKx1ViJcm06aJQun3339Hp9MREBBAXFwcbm5uzJs3D19fXxwcHJSOJ4qokiVL4uPjg4+PD3FxcQQGBuLv70+XLl1wdHTE19cXrVZLnTp1lI4qxAuRIwOi0EhKSuLrr7+madOmuLm58f3339OnTx/OnDnD5cuXmTFjhhQBUWAcHByYMWMG4eHhnDlzht69e7Ny5Urc3Nxo1qwZX3/9NUlJSUrHFCJXpAwIk5aZmcmOHTsYMGAA9vb2TJo0CY1Gw+bNm4mLi2P58uV4eHjIaQChGJVKhYeHB8uXLyc+Pp7NmzdjZ2fHpEmTsLe3Z8CAAezYsYOsrCylowrxVFIGhEm6ePEiU6dOxcnJCS8vL65fv87ChQuJjY0lODiYfv36YWVlpXRMIR5jZWVFv379CAkJITY2loULF3Lt2jW8vLxwcnLinXfe4eLFi0rHFOIJUgaEybh79y5ffPEFjRo1omHDhgQGBjJkyBDOnTvH+fPnmTJlCpUrV1Y6phC5UrlyZaZMmcKFCxc4d+4cPj4+rFmzhoYNG/L666/zxRdfcPfuXaVjCgFIGRAKy8jIYNu2bfTq1QsHBwemT5+Oi4sL27dvJzY2lqVLl+Lu7q50TCFeibu7O8uWLSMuLo7t27dTrVo1pk+fjoODA71792bbtm1kZGQoHVMUY1IGRIEzGo388ssvTJw4EQcHB/r27UtcXBxLly4lPj6eLVu24O3tjYWFhdJRhchTFhYWeHt7s3XrVuLi4vj888+JiYmhb9++ODg4MGnSJH799VdZNEkUOCkDosDEx8ezZMkS6tevT5MmTdiyZQsjRozg8uXLhIWFMWHCBGxtbZWOKUSBqFixIhMnTuTs2bNcunSJN998k02bNtG4cWMaNGjAkiVL0Ov1SscUxYRJLFSUkpIi64oXUenp6Rw+fJiQkBBOnjyJubk5np6e9OzZk2bNmmFuLlNdKG3y5MkALFu2TNEcArKysjh16hQ7duzg0KFDZGdn06JFC7y8vGjTpo1cNFuElSpVChsbmzzfbm7334qXgZSUFFasWEFmZmaeblcIIYQoLCwsLBg/fnyeF4Lc7r8V/2tZamoqmZmZ9OnTh0qVKikdR7yCO3fusHPnTnbs2MHt27exs7OjZ8+e9OjRg2rVqikdTzyFHBkwfZGRkezYsYOdO3eSkJBA1apV8fLyonv37nKHTRFw9+5dtm3bRmpqar4cHcgNxcvAXypVqoS9vb3SMcQLSk1NZdu2beh0Ovbv30+JEiXo168f8+fPx9PTEzMzM6Ujiud49OgRgIw/E2Zvb0+LFi348MMPCQ0Nxd/fn48++og5c+bQsWNHtFotffr0oVSpUkpHFYWUXEAoXpjRaOTo0aOMGjUKjUaDr68v6enprFq1Cr1eT0BAAB07dpQiIEQeMzMzo2PHjgQGBqLX6/n+++9JS0vD19cXjUbDqFGjOHbsmNyNIF6YlAGRa5GRkXz44YfUqFGDNm3acPDgQaZOncqNGzc4fPgwI0aMyJcLTIUQTypbtiwjR47kyJEjREREMGXKFA4cOEDr1q1xdXXlww8/JDIyUumYopCQMiCe6cGDB/j7+9OuXTuqV6/O4sWLadu2LYcOHSIiIoK5c+fi4uKidEwhirXXXnuNefPmcePGDUJDQ2ndujWLFi2ievXqeHp6otPpePDggdIxhQmTMiCeYDAYOHjwIFqtlsqVKzNixAjMzc1Zs2YNer2eH374gbZt26JWyx8fIUyJWq2mXbt2/Pjjj+j1enQ6HWq1Gj8/PzQaDVqtltDQUAwGg9JRhYmRb3ORIyIigvfee4/q1avToUMHTpw4waxZs4iMjGT//v0MGzaM0qVLKx1TCJEL1tbWDB8+nAMHDhAZGcnMmTM5ceIE7du3x8XFhffff5+IiAilYwoTIWWgmEtJSeH777+nVatWuLq68uWXX9K1a1eOHz/OtWvXmD17Ns7OzkrHFEK8gqpVqzJnzhyuXbvGsWPH6Ny5M1988QWurq60atWKVatWkZKSonRMoSApA8VQdnY2P//8M0OGDEGj0TBmzBisra1Zv349er2e7777jpYtW6JSqZSOKoTIQyqVijfeeIOVK1ei1+tZv3491tbWjB49Go1Gw5AhQ9i7dy/Z2dlKRxUFzGTmGRD57/fff0en0xEQEEBcXBxubm7MmzcPX19fHBwclI4nhChAJUuWxMfHBx8fH2JjYwkMDESn09GlSxccHR3x9fVFq9VSp04dpaOKAiBHBoq4pKQkvv76a5o1a4abmxsrV66kT58+nDlzhsuXLzNjxgwpAkIUc46Ojrz77ruEh4dz5swZevXqxcqVK3Fzc6NZs2Z8/fXXJCUlKR1T5CMpA0VQZmYmO3bsYMCAAdjb2zNp0iQqV67M5s2biY+PZ/ny5Xh4eMhpACHEY1QqFR4eHqxYsYL4+Hg2bdqEnZ0dkyZNwt7engEDBrBz506ysrKUjirymJSBIuTixYu88847ODk54eXlxbVr11i4cCGxsbEEBwfTr18/WfVMCJErVlZW9O/fn5CQEGJjY/nkk0+4evUqPXv2xMnJiXfeeYdLly4pHVPkESkDhdzdu3f54osveP3112nYsCEBAQEMGTKEc+fOceHCBaZMmSILmQghXknlypWZOnUqFy5c4Ndff8XHx4c1a9bQoEEDXn/9db788kvu3r2rdEzxCqQMFEIZGRls27aN3r174+DgwPTp06levTrbt28nNjaWpUuX4u7urnRMIUQRo1KpaNSoEcuWLSM2NpaffvqJatWqMW3aNBwcHOjduzc//fQTGRkZSkcVL0jKQCFhNBr55ZdfmDRpEg4ODvTt25eYmBiWLl1KXFwcW7ZswdvbGwsLC6WjCiGKAUtLS3r16sXWrVuJi4vj888/JyYmhj59+uDo6Mjbb7/Nr7/+KosmFRJSBkxcfHw8S5YsoUGDBjRp0oRNmzYxYsQILl++zNmzZ5kwYQIVK1ZUOqYQohirWLEiEydO5OzZs1y6dAk/Pz82btxI48aNadCgAZ999hl6vV7pmOIZpAyYoLS0NDZu3EiPHj1wcnJizpw5uLm5sWvXLqKjo1m0aBF169ZVOqYoxHbu3Im5uTlqtZqQkBBCQkJQq9WYm5uzc+dOpeOJQqxevXosXryY6Ohodu7ciZubG7Nnz8bJyYkePXqwadMm0tLSlI4p/oeUARNhNBo5deoUY8eOxd7enkGDBuXMERAfH09QUBDdunXD3FzmiRKvrnr16hgMhscO4RqNRgwGA9WrV1cwmSgqzM3N6d69O0FBQTm3NCclJTFw4EDs7e0ZO3Ysp0+fltMIJkLKgMJiYmL45JNPqFOnDi1atGDHjh2MGzeOK1eucPLkSUaPHk358uWVjimKGDc3N/r37/9YuTQ3N2fgwIG4ubkpmEwUReXLl2fMmDGcPHmSK1euMHbsWHbs2EHz5s2pU6cOCxcuJCYmRumYxZqUAQWkpqaydu1aOnfujLOzM/Pnz8fDw4N9+/YRGRnJxx9/TK1atZSOKYq4Dz744LE56LOzs3n//fcVTCSKg1q1arFgwQIiIyPZu3cvTZo04cMPP8TZ2ZnOnTuzbt06UlNTlY5Z7EgZKCBGo5GjR48yatQoNBoNvr6+pKWlsWrVKvR6PQEBAXTs2BEzMzOlo4piom7duvTv3x+VSoVKpZKjAqJAmZmZ0alTJwIDA9Hr9Xz//fekpaUxdOhQNBoN//rXvzh27JicRiggUgbyWWRkJB9++CGurq60adOGAwcOMHXqVG7cuMGRI0cYMWIEZcuWVTqmKKY++OADjEYjRqNRjgoIxZQtW5aRI0dy5MgRIiIimDJlCvv376d169a4uroyf/58bt++rXTMIk3KQD548OAB/v7+eHp6Ur16dRYtWkTr1q05dOgQN27cYO7cubi4uCgdUwjq1q1Ls2bNaN68uRwVECbhtddeY968edy4cYPQ0FBat27Np59+SrVq1fD09ESn0/HgwQOlYxY5RaoMPEzPIjwuhXNR/yE8LoWH6QW3mIbBYODgwYNotVo0Gg0jRoxArVazZs0a7ty5w48//kjbtm1Rq4vU/3JRyD1Mz2L11p/5OmhXgY8ZIZ5FrVbTrl07fvzxR/R6PTqdDrVajZ+fHxqNBq1WS2hoKAaDoUBzKbmfyU+F/j6163fus/Z0FKFXE4hKSuXvZ5dUgHOFUnjWsmNoM2dcK5fJ8/ePiIhAp9OxZs0aoqKiqFGjBjNnzmTYsGFUrVo1z99PiFel9JgR4kVZW1szfPhwhg8fzu3btwkICMj53q1atWrOczVq1MiX9y8OY0ZlzMXVGffu3cPGxoaUlJQ8P78dHx/PypUreeutt7C3t8/1z0UnpTJr2yWORvyBmVpFtuHpH+Ov51vXqMiCPvWpUqHUM7ednZ1NVlbWU1f4S0lJYePGjeh0Oo4fP07ZsmUZNGgQfn5+tGjRQpYGFiYpP8eMEAXNaDRy4sQJdDodQUFB3Lt3jzfeeAM/Pz8GDBiAjY3NP/5ceno65ubmubpYu6DGzMvuB3Mjt/vvQnnMekNYFB2XHubEzUSAZ/6C/v78iZuJdFx6mA1hUU99bWJiIvXq1WPAgAGPbyM7m7179zJkyBA0Gg1jxozB2tqa9evXo9frWblyJS1btpQiIExSfo4ZIZSgUql44403WLlyJXq9nnXr1mFtbc3o0aPRaDQMGTKEvXv3Pnb7LED//v2pV68eiYmJz9x+cRszhe40wfLQ6yzZe+2lfjbbYCTbYGTm1kv88SCdCZ6ujz1///59OnXqxJUrV7h69SqxsbHcu3cPnU5HYGAgsbGx1KlTh7lz5+Lr64ujo2NefCQh8lV+jhkhTEHJkiUZPHgwgwcPJjY2lsDAQHQ6HV26dMHR0ZFhw4ah1WqxtrZm586dGI1GOnfuzKFDhyhT5snD+sVxzBSqIwMbwqJe+hf0v5bsvUbQ35pbWloaPXv25OLFizmP/XWF9cqVK+nduzdnzpwhPDycd999V4qAKBTyc8wIYYocHR159913CQ8P5/Tp0/Tq1YvvvvsuZ5bXv1y4cAEvL68n1kkormPGJMuAv78/KpWKEiVK5NxbGp2UygfB4QDo184kbtW4nNfHfD2C2wt7krhn+RPbSrt9kdsLe/LwyrHHHjdkPGLMhElU1thTokQJKleuzJEjR3IOKRmNRpKSkti0aVPOvNoeHh5yGkCYpPweM4b0VP4T+gMjBvXGtmIlVCoVc+fOzd8PJcQrUKlUNG3alBUrVhAfH8/GjRtJSkrKmcQoOzubw4cPU7p0aW7cuAHk7Zh5FHmBP3YuY1i3NyhVujSOjo706tWLX375JT8/9kszyTLwl/T0dObMmQPArG2XyHrOOZsHF/eRmZi7+a3vbl3AvYv7qdZZS40aNbh3794Tr0lNTaVKlSpPvZBQCFOTX2PG8Og+98//jCErkwpuLfMkqxAFxcrKiipVqvzjNMcGgyHniEFejpkH53aRlZKATRNvWo1fwhdffEFCQgLNmzfn4MGDL/dB8pFJl4GuXbuybt06gg+e4GjEH8+8gMPKsTYqixIkH17z3O0+uhFGWuQ5KnQexx3H1piVd6R06dL/+NqffvrpZeMLUeDya8yY2dhRZfIGKg9dSFqjQXkZWYgCsX379n983MzMjLt37+b5mKnQeSyaIQso3ag718yccW/ThX379mFra8uCBQte+nPkF5MuAzNmzMDW1pap02Zgpn724Xl1iTLYNO9P6rUTpMdeeeZrU6+dRGVZklK1W2GmVtFn+uc8ePCAwMBAAH744QeCg4P55ptvGDFiRJ59HiHyW36Nmb/WLwCeu10hTNGIESP45ptvCA4O5pdffuGLL74AYN++fVSqVCnPx4xZ6XL//+9qFYGnorC2tsbNzY3o6OhX/jx5zaTLQJkyZZgzZw43zh3nwc3zz399E2/Mytjyn9Afn/m6jLu3sbB1QqU2I9tgJPRaAgDu7u4AZGZm4uXlxZgxY3B1LRxXggoB+Tdm/u55t1gJYYpcXV0ZM2YMXl5evP766zn33BfUmAm9lkBKSgq//vordevWfdmPkW9MugwA+L45CvNyGpIP+T939Sq1hRU2rYaQHhNOasSZp77O8Og+6hL/fztJVGIqD9OzqFChAsBz7z8VwpTlx5j5JxlZBTsNrBD5pSDGTFRiKqPHjOXhw4fMnj37VSPnOZMvA/H3MynXZhgZ+uukXjn63Ndb1++IRUXn//5Sn/Fl9be7AoxAZOLDvz0lh0FF4ZVvY+Z/JD/KeJWYQpiMghgz/zkSQNCG9SxdupTGjRu/auQ8Z/JlICPLQKk6bbCs/BrJhwMwZj97UQiV2oxybYaT+UcUDy8d+MfXqEuWwfDo8bsHMrIMJCUlAeQcIRCiMMqPMfNP5HSBKCrye8wkH1tHyokgxk+fw4QJE/Iqdp4y+TJgaa5GpVJRzvNNspLjeXB+z3N/plTN5lg5uZF8bB3G7Mwnt1mpGpmJMRgN/z9NpaW5mkuXLgFQr169vPsAQhSw/Bgz/0QuJBRFRX6OmeRj60g5tg6bVkMYO3laXsbOUyZfBqrZlkYFlKzmTolqjUg+vgFjZtpzf65cOz+y793l3tngJ54rVbMFxoxHpF49Dvy56lQ129LodDocHBxo1qxZHn8KIQpOfoyZf3x9SctXTCqEacivMZN8fP2fRaDlIMq3GkI123++hd0UmHwZKG1ljvN/V38q384PQ2oKGfqI5/5cCSc3Sro2J+3mk7M9lXytCSWqNSLp56+5f34PVvqLTJ4wlj179rBo0aJcrWYlhKnKjzED8OjGWR5eOcaj/140FXHtCps3b2bz5s3/OJmLEIVBdnY2J48eopThzz/DeTVm7p3eSsrRtZRwaUzJ1zwo9yCSS+fOcurUKU6dOpXXH+OVFYqFijxr2RFw+jaWmtco5daG1N8O5+rnyrfV/vnF9Q8XeFTqO4vkw2tIObqWpNQUbpqb0atXLzw8PPI6vhAFLj/GTOLPX5N9LyHnvzdt2sSmTZsAuHXrFtWqVcuT7EIUBL1eD4C3tzcJCQm4DHgXsxqt82zM/HWnQdrNX9Df/AU90OJvMxk/766FgqYy5iJRbtdDfhm5Wcf5+p37dFp2JE/f9+8+a2/D/q1rWb9+PSkpKbRo0QKtVsugQYMoV65cvr2vEPklv8fM/iltqGH35GpvQpiy5ORkgoKC8Pf359SpU5QrVw4fHx+0Wi0VqrnR+Yvn30nwsp41ZnKzH3xZud1/m/xpAgDXymVoXaNinl+wZKZW0bpGRfp1asU333yDXq8nKCiIcuXKMW7cODQaDT4+PuzevZusrGdfXSqEKcnvMSNFQBQWWVlZ7N69Gx8fHzQaDePGjaNChQoEBQURHx/PN998Q/PmzampKVusx0yhKAMAC/rUxzyPf0nmahUL+tTP+e8SJUowcOBAdu3aRUxMDB999BGXL1+me/fuODs7M2PGDMLDw/M0gxD5pSDGjBCmKjw8nBkzZlClShW6d+/O5cuX+eijj4iJiWHnzp0MHDiQEiVKPPYzxXnMFJoyUKVCKeZ55+0Ujh9616XKfy+0+l/29vZMmzaNS5cucfbsWfr3788PP/xAvXr18PDwYPny5TJToTBpBT1mhFBaYmIiy5cvp0mTJtSrV48ffviBAQMGcPbsWS5dusS0adOeeRi+OI+ZQlMGAHw8nJnWuWaebGt651oM8nB+7utUKhWNGzfmyy+/JC4ujq1bt+Lo6MiUKVOwt7enX79+BAcHk5mZu3uzhShISowZIQpSZmYmwcHB9OvXD3t7e6ZMmYKTkxNbt24lLi6OL7/8ksaNG+d6ZtniOmYKVRkAmODpysK+9bEyV7/wuR0ztQorczWf9q3PeM8aL/zelpaW9OnTh59++onY2FgWL17MzZs36dWrV05BuHDhwgtvV4j8pOSYESK/nD9/nilTpuDo6EivXr24desWixcvJi4ujp9++ok+ffpgaflyc2EUxzFT6MoA/Nnc9k9pS0sXW+D5M6H99XxLF1v2T2mbJ03Nzs6Ot99+m3PnznHhwgWGDRvGunXrcHd3x93dnaVLl5KQkPD8DQlRAExhzAjxqu7cucPSpUtxd3enUaNGrFu3jmHDhnHhwgV+/fVX3n77bSpVqpQn71XcxkyhuLXwWa7fuc/a01GEXksgKjGVv38YFeBsWwrPmnb4NnfO96s5MzMz+fnnn/H39yckJITs7Gy6d++OVqulZ8+eWFlZ5ev7C5EbpjRmhHie9PR0duzYgb+/P7t378bMzAxvb2+0Wi1dunTBwsIi3zPk95gxhVsLC30Z+LuH6VlEJj4kI8uApbmaaralKW2lzLxKSUlJbNiwAX9/f8LCwqhQoQKDBw9Gq9XSpEkTWRlRmISH6Vn0HvYvjCozvlj6maJjRoi/GI1Gzp49i06nY/369SQlJdG0aVO0Wi0+Pj6KLiaXH/sZUygDRWrUl7Yyp66DjdIxgD9XPhw3bhzjxo3jt99+Q6fTERgYyIoVK3Bzc0Or1eLr64uDg4PSUUUxVtrKnJJpf94VYypjRxRfcXFxBAYG4u/vz++//46DgwP/+te/0Gq11KlTR+l4gGntZ/JSobxmoLBxc3Pj008/JSoqij179tCgQQM++OADqlSpQrdu3diwYQOPHj1SOqYQQhS4R48esWHDBrp160aVKlX44IMPcHd3Z8+ePURFRbFw4UKTKQJFmZSBAmRmZkaXLl1Yv359zsxX9+7dY/Dgwdjb2zN69GhOnjxpcnNWCyFEXjIajZw4cYLRo0djb2/P4MGDuXfvHt9++y16vZ5169bRpUsXWTSuAEkZUEi5cuV46623OH78OFevXmXChAns3r2bli1bUqtWLT7++GOioqKUjimEEHkmKiqKjz/+mFq1avHGG2+we/duJk6cyLVr1zh+/Dj/+te/sLEpeofgCwMpAyagZs2afPTRR0RGRrJ//36aN2/OggULqFatGh07diQwMJCHDx8qHVMIIV7Yw4cPCQgIoGPHjlSrVo0FCxbQvHlzDhw4QGRkJPPnz8fV1VXpmMWelAETolar6dChA2vWrEGv17N69WqysrIYNmwYGo2GESNGcOTIEQyGJ5eXFUIIU2EwGDh8+DAjRoxAo9EwfPhwsrKy+OGHH9Dr9axZs4b27dujVssuyFTIb8JElSlThjfffJNDhw5x8+ZNpk2bxqFDh2jbti01atRg3rx53Lp1S+mYQgiR4+bNm8ydO5caNWrQrl07Dh8+zPTp07l58yaHDh3Cz8+PMmVk7gpTJGWgEKhevToffPABERERHD58GE9PTz777DNcXFxo27YtP/74I/fv31c6phCiGLp//z4//PADbdu25bXXXuPzzz/H09OTI0eOEBERwfvvv0/16tWVjimeQ8pAIaJWq2nTpg2rV69Gr9cTGBiIpaUlI0eORKPRMGzYMA4cOCCnEYQQ+cpgMLB///6cU5ijRo3CysqKwMDAnFOcrVu3lsnVChEpA4VUqVKlGDp0KPv27eP27dvMnj2bM2fO5FykM2fOHK5fv650TCFEEXLt2jVmz55NtWrV6NSpE2fOnGHOnDncvn2bvXv3MnToUEqVMv3lesWTpAwUAVWqVGHWrFlcuXKFkydP0r17d5YvX07NmjVp2bIlK1euJDk5WemYQohCKDk5me+++y7ntucVK1bQo0cPTp48yZUrV/j3v/9NlSpVlI4pXpGUgSJEpVLRvHnznIk7NmzYQLly5Rg7diwajQYfHx/27NlDdna20lGFECYsKyuL3bt34+Pjg0ajYdy4cZQrV46goCD0ej3ffPMNzZs3l9MARYiUgSKqRIkSDBo0iF27dhEdHc38+fO5fPlyzpSfM2bMIDw8XOmYQggTEh4ezowZM3B2dqZ79+5cvnyZjz76iJiYGHbt2sXAgQMpUaKE0jFFPpAyUAw4ODgwffp0Ll26RFhYGP369WP16tXUq1cPDw8PVqxYQWJiotIxhRAKSExMZPny5Xh4eFCvXj1Wr15Nv379OHv2LJcuXWLatGl5vpKeMD1SBooRlUpFkyZN+Oqrr4iLi2PLli04ODgwefJk7O3t6devHyEhIWRmZiodVQiRjzIzMwkODqZfv37Y29szZcoUHBwc2Lp1K/Hx8Xz11Vc0btxYTgMUI1IGiikrKyv69u3L9u3biY2NZdGiRdy8eRNvb2+cnJyYOnUqFy5cUDqmECIPXbhwgSlTpuDo6EivXr24efMmixYtIjY2lu3bt9OnTx8sLS2VjikUIGVAYGdnx+TJkzl37hznz59n6NChBAYG4u7ujru7O8uWLSMhIUHpmEKIl5CQkMDSpUtzxvO6devw9fXl/PnznDt3jsmTJ2NnZ6d0TKEwKQPiMQ0bNuTzzz8nNjaW4OBgatSowYwZM3L+JrF161YyMjKUjimEeIb09HS2bt2Kt7c3jo6OzJw5kxo1ahAcHExMTAyff/45DRs2VDqmMCFSBsQ/srCwwMvLi82bNxMfH8+yZcuIi4vLOcc4ceJEzp49i9FoVDqqEAIwGo2cPXuWCRMm4ODgQL9+/dDr9Tljd/PmzXh5eWFhYaF0VGGCpAyI57K1tWX8+PGEhYURHh7OqFGj2LJlCx4eHtSvX5/FixcTHx+vdEwhiqX4+HgWL16cc3fQ1q1bGTVqFOHh4Zw5c4bx48dja2urdExh4qQMiBfi5ubGp59+SlRUFLt376Z+/fq89957ODk50b17d4KCgkhLS1M6phBFWlpaGkFBQXTr1g0nJyfef/99GjRowO7du4mKiuLTTz/Fzc1N6ZiiEJEyIF6Kubk5Xbt2Zf369TkzkqWkpODj44O9vT1jxozh5MmTchpBiDxiNBo5efIkY8aMyZlR9N69e3zzzTfEx8ezfv16unbtirm5udJRRSEkZUC8snLlyvHWW29x/Phxrl69yvjx49m1axctW7akdu3aLFiwgOjoaKVjClEoRUdHs2DBAmrXrk3Lli3ZtWsXEyZM4OrVqxw/fpy33nqLcuXKKR1TFHImUyHv3r2rdASRB8qUKcP48eMZO3YsZ8+eJSQkhFWrVrF8+XKaNm2Kl5cXnp6elCxZUumo4r/++l3IdR+m49GjR4SGhhIcHExYWBglSpSgffv2LFq0iCZNmqBW//n3OPmdFQ2msP9TGXNxHPfevXvY2NiQkpJC2bJl8zRASkoKK1askFnvhBBCFFsWFhaMHz8eGxubPN1ubvffih8ZsLGxYfz48aSmpiodRRSAvxY8CQkJIS4uDgcHB7y8vOjRoweOjo5KxyuWJk+eDMCyZcsUzVFcxcbGsnPnThkTxVypUqXyvAi8CMWPDIjiyWAwcOzYMXQ6HRs3buTBgwe0bdsWrVZL//79KVOmjNIRiw1vb28AgoODFU5SfNy/f5/Nmzfj7+/PkSNHsLa2ZuDAgWi1Wlq1apVzGkCIV5Xb/bf8iROKUKvVtGnThtWrV6PX6wkICMDc3JyRI0ei0WgYPnw4Bw4cwGAwKB1ViDxhMBg4cOAAw4YNQ6PRMHLkSCwtLQkICECv17N69WratGkjRUAoQv7UCcWVLl0aX19f9u/fT2RkJLNnz+bUqVN07NiR6tWrM2fOHK5fv650TCFeyvXr15kzZw7VqlWjY8eOnDlzhtmzZ3P79m327duHr68vpUuXVjqmKOakDAiT4uzszKxZs7h69SonTpygW7duLF++nJo1a/LGG2+wcuVKkpOTlY4pxDMlJyezcuVKWrZsSc2aNVm+fDndu3fnxIkTXLlyhVmzZlGlShWlYwqRQ8qAMEkqlYoWLVrw7bffEh8fz4YNG7CxsWHs2LHY29szePBg9uzZQ3Z2ttJRhQAgOzubPXv24OPjg0ajYezYsZQrV44NGzag1+v59ttvadGiBSqVSumoQjxByoAweSVLlmTQoEHs2rWL6OhoPvzwQy5evEi3bt2oUqUK7777Lr/99pvSMUUxFR4ezowZM6hSpQrdunXj8uXLzJ8/n+joaHbt2sWgQYMoUaKE0jGFeCYpA6JQcXBwYPr06Vy+fJmwsDD69evHqlWrqFu3Lk2bNmXFihUkJiYqHVMUcYmJiaxYsQIPDw/q1avH6tWr6devH2FhYVy6dInp06fj4OCgdEwhck3KgCiUVCoVTZo04auvviIuLo4tW7ag0Wh4++23sbe3p3///oSEhMhkViLPZGZmEhISkrOM9+TJk3FwcGDLli3ExcXx1Vdf0aRJEzkNIAolKQOi0LOysqJv374EBwcTFxfHokWLiIiIwNvbGycnJ6ZOncqFCxeUjikKqQsXLjB16lScnJzw9vbm5s2bLFq0iNjYWLZv307fvn2xsrJSOqYQr0TKgChS7OzsmDx5MufPn+fcuXMMGTKEwMBA3N3dadSoEcuWLSMhIUHpmMLEJSQksGzZMtzd3XF3dycwMJChQ4fm/LmaPHkydnZ2SscUIs9IGRBFlru7O0uXLiU2Npbg4GBcXFyYMWMGjo6O9OrVi61bt5KRkaF0TGEiMjIy2Lp1K7169cLR0ZF3332XGjVqEBwcTGxsLJ9//jkNGzZUOqYQ+ULKgCjyLCws8PLyYsuWLcTHx7Ns2TLi4uLo168fDg4OTJw4kV9++YVczMwtihij0cjZs2eZOHEi9vb29OvX77E/I5s3b8bLywsLCwulowqRr6QMiGLF1taW8ePHExYWRnh4OCNHjmTLli00adKE+vXrs3jxYlkWthiIj49n8eLF1KtXDw8PD7Zs2cKoUaMIDw/nzJkzjB8/HltbW6VjClFgpAyIYsvNzY1PP/2UqKgodu/eTf369XnvvfdwcnKie/fuBAUFkZaWpnRMkUfS0tIICgqiW7duODk58d5779GgQQN2795NVFQUn376KW5ubkrHFEIRUgZEsWdubk7Xrl1Zv349er2eb775huTkZHx8fLC3t2fMmDGcPHlSTiMUQkajkZMnTzJmzBg0Gg0+Pj7cu3ePb775Br1ez/r16+natSvm5oqv5i6EoqQMCPE35cqV46233uLEiRNcvXqV8ePHs2vXLlq2bEnt2rVZsGAB0dHRSscUzxEdHc2CBQuoXbs2LVu2ZNeuXUyYMIGrV69y/Phx3nrrLcqVK6d0TCFMhsqYi7/u5HY9ZCGKIoPBQGhoKP7+/mzZsoW0tDQ6dOiAVqulb9++lCpVSumIL+zq1at8+umnZGdnc/DgQQDat2+PmZkZ7777LrVq1VI44Yt7+PAh27ZtQ6fTceDAAUqWLEm/fv3QarV4enrK0sCiWMrt/lvKgBAv4P79+2zevBl/f3+OHDlCmTJlGDBgAFqtltatWxea2edCQkLw9vZGrVZjMBgAcv49ODgYLy8vhRPmjtFo5OjRo+h0OjZu3MiDBw9o27YtWq2W/v37U6ZMGaUjCqEoKQNC5LObN2+yZs0a1qxZw61bt3BxcWH48OEMHz6c6tWrKx3vmQwGA3Xq1CEiIuKxMlCjRg1+//13k/9b9K1bt1izZg06nY5bt25RvXp1tFotw4YNw8XFRel4QpgMKQNCFBCDwcCxY8cK3d9ON27cyKBBgx57LCgoiIEDByqU6Nn+Oiqj0+k4fPgw1tbWDBw4EK1WS6tWrUy+wAihBCkDQijgr/PW/v7+HDx40KTPW/91dODatWsA1KxZ0+SOCvz9eo2tW7fy6NGjnOs1+vTpQ+nSpZWOKIRJkzIghMKioqIIDAzE39+f69ev4+zszLBhw9Bqtbi6uiodD3j86IApHRW4fv06Op2ONWvWEB0dTc2aNXNOA1SpUkXpeEIUGlIGhDARRqORU6dO4e/vT1BQECkpKbRs2RKtVsvAgQMVvcXNYDDkvH9ycrKiRwWSk5PZuHEj/v7+nDx5EhsbG3x8fNBqtTRv3rzQXJwphCmRMiCECXr06BHBwcH4+/uzd+9eLC0t6d27N1qtlk6dOmFmZlageR6mZ3Hg9EUyDUZq16xBNdvSlLYquAl4srOz2bdvHzqdjm3btpGZmUmXLl3QarV4e3tTsmTJAssiRFEkZUAIExcXF0dgYCA6nY7ffvsNBwcHfH190Wq1+Tot7vU791l7OorQqwlEJaXy9y8AFeBcoRSetewY2swZ18r5c/Hjb7/9hk6nIyAggPj4eNzc3PDz82Po0KE4ODjky3sKURxJGRCikDAajfzyyy/4+/uzfv16kpKS8PDwQKvVMnjwYCpUqJAn7xOdlMqsbZc4GvEHZmoV2YanD/2/nm9doyIL+tSnSoVXn1gpMTGRDRs2oNPpCAsLo0KFCgwZMgStVkvjxo3lNIAQ+UDKgBCFUHp6Ojt37sTf359du3ZhZmaGl5cXfn5+dOnS5YmldP39/bl16xZz58595s50Q1gUHwSHk2UwPrME/C8ztQpztYp53nXx8XD+x9cYjUbmzp2Li4sLWq32secyMzPZs2cPOp2O4OBgjEYj3bt3R6vV0qNHD6ysrHKdRQjx4qQMCFHIJSQksG7dOvz9/blw4QJ2dnYMHToUrVZLw4YNycrKQqPRkJiYyPTp01m0aNE/bmd56HWW7L32ynmmda7JBM/H74IwGo3MmDGDJUuWULFiReLj4zE3N+fChQvodDrWrl1LQkIC7u7uaLVahgwZgp2d3StnEULkjpQBIYqQ8+fP5+xc7969i7u7O02aNGHVqlU5r/nkk0+YOXPmYz+3ISyKmVsv5VmOT/vWZ9DfjhB88sknzJo1K+e///Wvf3HmzBkuXLhApUqVcq6BaNiwYZ5lEELknpQBIYqgvw67+/v7s23btieWVf72228ZPXo08Oc1Ah2XHibx170k7lr21G1WHryAElUbAPAo8jzJRwLITIhEZWFFydc8KO/5JmalywFgZa5m/5S2VKlQim+//ZaxY8c+ti2VSkXfvn3RarV07dr1idMaQoiCJWVAiCIsKSmJypUrk5WV9cRzixYtYvr06QxbfZoTNxNJOb+PxF3LsO0+GQtbpydeb1HRGbVVKdKiLnFnwxxKvuZBmdd7kJ2aTPIhf9QlrLHXLkNlboGZWkVLF1saJB1hxowZT2zL3NychIQEypcvny+fWwjxYnK7/zadeUeFELkWFBREVlYWKpUKCwuLxyYLeu+997h+5z5HI/547GJBi0pVsXKs/cQ/aqs/7xT4T+gPWFRwpFKff1OyeiOs63pSsddMMu/e5sHFfQBkG4wcjfiDuZ9/k7NdtVqNhYUFKpWKrKwsgoKCCuj/ghAirxTc7CJCiDxjb29P06ZNcXZ2xtHREScnJxwdHbG3t8fFxYUfTkc99/bBv8u6/wcZ8dcp11aLSv3/Ex+VcKqDeQVHUq+dpMzr3YE/7zAY89k6vBzSiI+PJzY2lpiYGGJjY4mKikKj0eTLZxZC5B8pA0IUQr1796Z3795PfT40KPTJImA0YDRkP/FaldqMzLu3AbC0q/bE85aVqpEe+3vOf2cbjJyNe8RnQzxfKrsQwvRIGRCiiHmQnkVUUuoTj+vXvPPki1Vqqr4bjOHRfQDUJZ6ccVBdsgzZj+499lhUYioP07MKdOpiIUT+kZEsRBFzO/Eh/3RywLbnVCxs/2fFv/+dqOipExc9/rgRiEx8SF0Hm5eNKYQwIVIGhChiMrIM//i4hW0VrOz/eelkdck/jwgY/ucIwJ+P3ces5JNHDJ72PkKIwkfuJhCiiLE0f/FhbVGpKgAZ/7124O8y7t7GomLVPHkfIYRpktEsRBFTzbY0L7rkj3mZilja1+RheOhjFxmmx14hKymGUrVaPPZ61X/fRwhRNMhpAiGKmJIWaiqXNkP/8PE7BzLv3oZ/uJvAvLw9ZqVsKN/OjztB73H3p4WUeb0HhofJ/OewDotKVbGu3+mxn3GuUEouHhSiCJEZCIUoIq5fv45OpyMgIID7NbtSzsMbgxEeXNz/zOmIK3SbSJmGXQB4dOscyUcDyUy4hcrcipI1PCjvOSJnOmLgzyMH148wvG5JtFotNWrUyOdPJoR4WTIdsRDFQEpKChs3bsTf358TJ05gY2PDoEGD6NDXlxmHnrwYMK+8kXyQnetXk5KSwhtvvIFWq2XgwIHY2MjdBUKYEpmOWIgiKjs7mz179jB48GA0Gg1jxoyhbNmybNiwgfj4eL777jsGdmlN6xoVMVO/6NUDz2amVtG6RkXWfvMZ8fHxrF+/njJlyjBmzBg0Gg1Dhgzh559/Jjv7ydMRQgjTJUcGhCgkfvvtN3Q6HYGBgcTFxeHm5oZWq8XX1xcHB4cnXv/XqoXpeXgL4N9XLfy7uLg4AgMD0el0/Pbbbzg4ODBs2DC0Wi116tTJs/cXQrwYOU0gRBGQlJTE+vXr0el0hIWFUaFCBQYPHoyfnx+NGzdG9dRJgv60ISyKmVsv5VmeT/vWZ5CH81OfNxqNnD17Fp1Ox7p16/jPf/6Dh4cHfn5++Pj4UKFChTzLIoR4PikDQhRSmZmZ/Pzzz/j7+xMSEkJ2djbdu3dHq9XSs2dPrKysXmh7y0Ovs2TvtVfONb1zLcZ75v5iwfT0dHbs2IFOp2PXrl2YmZnh7e2NVqulS5cuWFhYvHImIcSzSRkQopC5ePEi/v7+rF27loSEBBo2bIhWq2XIkCFUrlz5lba9ISyKD4LDyTIYc72SIfx5jYC5WsWH3nWfeUTgee7cucO6devw9/fn4sWL2NnZ4evri1arpUGDBi+9XSHEs0kZEKIQuHv3bs5O8vz581SqVImhQ4ei1Wpxd3fP0/eKTkpl1rZLHI3447nLG//1fOsaFVnQp/4T1wi8ivPnz6PT6Vi7di13796lUaNGOaWnUqVKefY+QggpA0KYrIyMDHbu3Im/vz+7du1CpVLh5eWFVqulW7du+X74/Pqd+6w9HUXotQSiElMfW9RIBTjblsKzph2+zZ2pYffkmgR5JTMzk927d6PT6QgJCcFoNNKjRw+0Wi09evTA0tIy395biOJCyoAQJsRoNPLrr7/i7+/P+vXrSUxMpEmTJmi1WgYPHoytra0iuR6mZ9F72L8wqsz4YulnVLMtrcjMgn/88QcbNmzA39+fX375BVtbW4YMGYJWq+X1119/7oWSQoh/JmVACBMQHx/P2rVr8ff3Jzw8HHt7+5xz5XXr1lU6HgDe3t4ABAcHK5zkT+Hh4TkzKer1eurVq4dWq2Xo0KHY29srHU+IQkUmHRJCIWlpaWzcuJHu3bvj5OTEnDlzqFevHrt27SIqKopFixaZTBEwRXXr1mXRokVER0eza9cu3NzcmDNnDk5OTvTo0YONGzeSlpamdEwhihQpA0LkAaPRyKlTpxg7diz29vYMGjSI5ORkvv76a+Lj49mwYQPdunXD3FwW98ktc3NzunXrRlBQEPHx8Xz99dckJSUxaNAg7O3tGTt2LKdOnSIXBzeFEM8hZUCIVxATE8Mnn3xCnTp1aNGiBTt27GDcuHFcuXKFEydOMHr0aMqXL690zEKvfPnyjB49mpMnT3LlyhXGjRvHjh07aNGiBXXq1OGTTz4hJiZG6ZhCFFpSBoR4Qampqaxdu5bOnTvj7OzM/Pnz8fDwYN++fURGRvLxxx9Tq1YtpWMWWbVq1eLjjz8mMjKSffv24eHhwfz583F2dqZz586sXbuW1NRUpWMKUahIGRAiF4xGI0ePHmXUqFFoNBp8fX1JT09n1apV6PV6AgIC6NixI2ZmZkpHLTbMzMzo2LFjzoWGq1atIi0tDV9fXzQaDaNGjeLo0aNyGkGIXJAyIMQzREZG8uGHH1KjRg3atGnDwYMHmTp1Kjdu3ODw4cOMGDFC7rAxAWXLlmXEiBEcOXKEGzduMHXqVA4cOECbNm1wdXXlww8/JDIyUumYQpgsKQNC/I8HDx7g7+9Pu3btqF69OosXL6Zt27YcOnSIiIgI5s6di4uLi9IxxVO4uLgwd+5cbty4waFDh2jdujWLFi2ievXqeHp64u/vz4MHD5SOKYRJkTIgBGAwGDh48CBarZbKlSszYsQIzM3NWbNmDXq9nh9++IG2bduiVsuQKSzUajVt27blxx9/5M6dO6xZswa1Ws2IESPQaDRotVoOHjyIwZB3SzwLUVjJN5so1iIiInjvvfeoXr06HTp04MSJE8yaNYvIyEj279/PsGHDKF26tNIxxSsqXbo0w4YN48CBA9y6dYuZM2dy4sQJOnToQPXq1XnvvfeIiIhQOqYQipEyIIqdlJQUvv/+e1q1aoWrqytffvklXbt25fjx41y7do3Zs2fj7PzyK/QJ01a1alXmzJnDtWvXOH78OF26dOHLL7/E1dWVVq1a8f3335OSkqJ0TCEKlJQBUSxkZ2fz888/M2TIEDQaDWPGjMHa2pr169ej1+v57rvvaNmypcyBX4yoVCpatmzJypUr0ev1rF+/Hmtra8aMGYNGo2HIkCHs3buX7OxspaMKke9kOjRRpP3+++8589zHxcVRp04d5s2bh6+vLw4ODkrHEyaiZMmS+Pj44OPjQ2xsLIGBgeh0Orp06YKjo2POehJ16tRROqoQ+UKODIgiJykpia+//ppmzZrh5ubGypUr6dOnD2fOnCE8PJwZM2ZIERBP5ejoyLvvvkt4eDhnzpyhV69erFy5Ejc3N5o1a5YzLbIQRYmUAVEkZGVlsWPHDgYMGIC9vT2TJk3Czs6OzZs3Ex8fz/Lly/Hw8JDTACLXVCoVHh4erFixgvj4eDZt2oSdnR2TJk3C3t6eAQMGsHPnTrKyspSOKsQrkzIgCrWLFy/yzjvv4OTkhJeXF9euXWPhwoXExsYSEhJCv379sLKyUjqmKOSsrKzo378/ISEhxMbG8sknn3Dt2jV69uyJk5MT77zzDpcuXVI6phAvTcqAKHTu3r3LF198weuvv07Dhg0JCAhg8ODBnDt3jgsXLjBlyhQqV66sdExRRFWuXJmpU6dy4cIFzp07h4+PD2vWrKFBgwa8/vrrfPnll9y9e1fpmEK8ECkDolDIyMhg27Zt9O7dGwcHB6ZPn0716tXZvn07sbGxLF26FHd3d6VjimLG3d2dZcuWERcXx/bt26lWrRrTpk3DwcGB3r1789NPP5GRkaF0TCGeS8qAMFlGo5FffvmFSZMm4eDgQN++fYmJiWHp0qXExcWxZcsWvL29sbCwUDqqKOYsLCzw9vZm69atxMXF8fnnnxMTE0OfPn1wdHRk0qRJ/Prrr7JokjBZUgaEyYmPj2fJkiU0aNCAJk2asGnTJkaMGMHly5c5e/YsEyZMoGLFikrHFOIfVaxYkYkTJ3L27FkuXbqEn58fmzZtonHjxjRo0IAlS5ag1+uVjinEY6QMCJOQlpbGxo0b6dGjB05OTsyZMwc3Nzd27dpFdHQ0ixYtom7dukrHFOKF1KtXj8WLFxMdHc3OnTtxc3Njzpw5ODk50aNHDzZt2kRaWprSMYWQMiCUYzQaOXXqFGPHjsXe3p5BgwblzBEQHx9PUFAQ3bp1w9xc5sYShZu5uTndu3cnKCgo51bXpKQkBg4ciL29PWPHjuX06dNyGkEoRsqAKHAxMTF88skn1KlThxYtWrBjxw7Gjh3LlStXOHnyJKNHj6Z8+fJKxxQiX5QvX54xY8Zw8uRJrly5wtixY9mxYwfNmzenTp06LFy4kJiYGKVjimJGZcxFFb137x42NjakpKRQtmzZPA+RkpJCampqnm9XmI60tDQOHjzIjh07OH36NFZWVrRv3x4vLy+aNGmCmZmZ0hGLrcmTJwOwbNkyRXMUZ9nZ2YSFhbFjxw4OHjxIeno6zZo1w8vLC09PT0qUKKF0RJHPSpUqhY2NTZ5vN7f7b8XLQEpKCitWrCAzMzNPtyuEEEIUFhYWFowfPz7PC0Fu99+Kn4xNTU0lMzOTPn36UKlSJaXjiDwQFxfHjh072LlzJzExMdjb29OzZ0969OhBlSpVlI4n/occGTBdf114uGPHDuLj43FycqJnz5707NkTe3t7peOJPHL37l22bdtGampqvhwdyA3Fy8BfKlWqJH+4C7EHDx6wZcsW/P39OXToEKVLl2bAgAEsWrSINm3aoFbL5Smm6tGjRwAy/kyQvb09TZs25YMPPuDIkSPodDoWLVrEBx98gKenJ1qtln79+mFtba10VFHIyTe0eGkGg4GDBw+i1WrRaDS8+eabqNVq1qxZw507d/jxxx9p166dFAEhXpFaraZdu3b8+OOP6PV6dDodKpUKPz8/NBoNfn5+hIaGYjAYlI4qCin5lhYvLCIigvfee4/q1avToUMHTpw4wcyZM7l16xYHDhxg2LBhlC5dWumYQhRJ1tbWDB8+nAMHDhAZGcnMmTM5fvw47du3x8XFhffff5+IiAilY4pCRsqAyJWUlBS+//57WrVqhaurK19++SVdunTh+PHjXLt2jTlz5lC1alWlYwpRrFStWpU5c+Zw7do1jh07RufOnfniiy9wdXWlVatWrFq1ipSUFKVjikJAyoB4quzsbPbu3cuQIUPQaDSMGTMGa2tr1q9fj16vZ+XKlbRs2RKVSqV0VCGKNZVKxRtvvMHKlSvR6/WsW7cOa2trRo8ejUajYciQIezdu5fs7GylowoTZTIXEArT8fvvv6PT6QgMDCQ2NpY6deowd+5cfH19cXR0VDqeEOIZSpYsyeDBgxk8eDCxsbEEBgai0+no0qULjo6ODBs2DK1WS+3atZWOKkyIHBkQADnTADdr1gw3NzdWrlxJr169OHPmDOHh4bz77rtSBIQoZBwdHXn33XcJDw/n9OnT9OrVi++++446derQrFkzvvnmG/7zn/8oHVOYACkDxVhWVhY7d+5kwIAB2NvbM2nSJOzs7Ni0aRPx8fGsWLECDw8POQ0gRCGnUqlo2rQpK1asID4+nk2bNmFnZ8fEiRPRaDQMHDiQnTt3kpWVpXRUoRApA8XQpUuXeOedd3ImMLl27RqffPIJsbGxhISE0L9/f6ysrJSOKYTIB1ZWVvTv35+QkJCcdUKuXLlCz549cXJyYtq0aVy6dEnpmKKASRkoJu7evcsXX3zB66+/ToMGDVizZg0+Pj6cO3eOCxcuMHXqVCpXrqx0TCFEAdJoNEydOpULFy7w66+/4uPjg06no0GDBrz++ut8+eWX3L17V+mYogBIGSjCMjIy2LZtG71798bBwYHp06dTrVo1tm/fTlxcHMuWLcPd3V3pmEIIhalUKho1asSyZcuIjY3lp59+olq1akybNg0HBwd69+7NTz/9REZGhtJRRT6RMlDEGI1Gfv31VyZNmoSDgwN9+/YlJiaGzz//nLi4OLZu3Yq3tzcWFhZKRxVCmCBLS0t69erF1q1biYuL4/PPPycmJoY+ffrg6OjI22+/za+//kou1rgThYiUgSJCr9ezZMkSGjRoQOPGjdm0aRNvvvkmly5d4uzZs0ycOJGKFSsqHVMIUYhUrFiRiRMncvbsWS5duoSfnx9BQUE0btyYBg0a8Nlnn6HX65WOKfKAlIFCLC0tjU2bNtGjRw+cnJyYM2cObm5u7Ny5k+joaBYvXky9evWUjimEKALq1avH4sWLiYmJYefOnbi5uTFr1qycC5E3bdpEWlqa0jHFS5IyUMgYjUZOnz7N2LFjsbe3Z+DAgSQlJbF8+XLi4+MJCgqie/fumJvLfFJCiLxnbm5O9+7dCQoKQq/Xs3z5cv744w8GDhyIvb0948aN4/Tp03IaoZCRMlBIxMTEsHDhQurUqUPz5s3ZsWMHY8eO5cqVK5w8eZIxY8ZQvnx5pWMKIYqR8uXLM2bMGE6dOsXvv//O2LFjCQkJoXnz5ri5ubFw4UJiY2OVjilyQcqACUtNTWXt2rV07twZZ2dnPvzwQ5o0acK+ffuIjIxkwYIF1KpVS+mYohDKzMwkNDSU/fv3c/fuXe7evcv+/fsJDQ0lMzNT6XiiEKpduzYLFiwgMjKSvXv30rhxYz788EOqVKlCly5dWLduHampqUrHFE8hx5JNjNFo5Pjx4/j7+7Nx40bu379P69at+f777xkwYABly5ZVOqIoAtavX49Wq33ssU6dOgGg0+kYPny4ErFEEWBmZkanTp3o1KkT9+7dY9OmTeh0OoYOHUqZMmUYNGgQWq2WN954Q2Y3NSFyZMBEREZG8uGHH+Lq6krr1q05cOAAU6ZMISIigiNHjjBy5EgpAiLP9OjRg5IlSz7xeKlSpejRo4cCiURRVLZsWUaOHMmRI0eIiIhgypQp7Nu3j9atW+Pq6sr8+fO5ffu20jEFUgYU9eDBA3Q6HZ6enlSvXp1FixbRunVrQkNDuXHjBvPmzeO1115TOqYogmxtbZkyZQpq9f9/BajVaqZMmYKtra2CyURR9dprrzFv3jxu3rxJaGgorVu35tNPP6VatWq0b98enU7HgwcPlI5ZbEkZKGAGg4HQ0FC0Wi0ajQY/Pz/UajU6nQ69Xs+PP/5Iu3btHvuSFiI/TJ069bE1KEqUKMGUKVMUTCSKA7VaTbt27fjxxx/R6/XodDpUKhV+fn4534mhoaEYDAaloxYrsscpIBEREbz//vu4uLjQvn17Tpw4wcyZM4mMjOTAgQMMHz4ca2trpWOKYuSvowN/kaMCoqBZW1szfPhwDhw4QGRkJDNnzuTYsWO0b98eFxcX3n//fSIiIpSOWSxIGchHKSkprFq1ilatWuHq6soXX3xB586dOXbsGNeuXWPOnDlUrVpV6ZiiGJs6dSpqtRozMzM5KiAUVbVqVebMmcP169c5duwYnTt35osvvsi5jmrVqlWkpKQoHbPIkjKQx7Kzs9m7dy9DhgxBo9EwevRorK2tWb9+PXq9npUrV8pVtMJk2NraMn36dKZNmyZHBYRJUKlUvPHGG6xcuRK9Xs+6desoXbo0o0ePRqPRMHToUPbu3Ut2drbSUYuUInVr4cP0LCITH5KRZcDSXE0129KUtiqYj/j777+j0+kIDAwkNjaWOnXqMHfuXHx9fXF0dCyQDEK8qIfpWQyb9G8ysgyEx6UU6JgR4nlKlizJ4MGDGTx4MLGxsQQGBqLT6Vi3bh2Ojo4MGzYMrVZL7dq1CyyTkvuZ/FToP8H1O/dZezqK0KsJRCWl8vcJMFWAc4VSeNayY2gzZ1wrl8nT905KSmLDhg3odDrOnDlD+fLlGTx4MH5+fjRp0kT+9i9MkpJjRoiX5ejoyLvvvsuMGTMICwtDp9Px3XffsXDhQpo2bYqfnx8+Pj75MhNrcRgzKmMuJpC+d+8eNjY2pKSk5Pm97vHx8axcuZK33noLe3v7XP9cdFIqs7Zd4mjEH5ipVWQbnv4x/nq+dY2KLOhTnyoVSj1z27///jtmZmbUrFnzieeysrL4+eef8ff3Jzg4mOzsbLp164ZWq8XLy+uxq7OFMCX5OWaEUEJ6ejohISHodDp2796NmZkZvXr1QqvV0qVLl39co+XatWtkZ2dTp06d526/oMbMy+4HcyO3++9Cec3AhrAoOi49zImbiQDP/AX9/fkTNxPpuPQwG8KinvraM2fO0LhxY3r16vXYQhuXLl3inXfeyVmh6+rVq3zyySfExsYSEhJC//79pQgIk5WfY0YIpVhZWdG/f39CQkKIiYnhk08+4cqVK/Ts2RMnJyemTZvGpUuXcl5vNBrx9vamcePGhIWFPXPbxW3MFLrTBMtDr7Nk77WX+tlsg5Fsg5GZWy/xx4N0Jni6PvZ8eHg4nTt3Ji0tjStXrnDw4EHCw8Px9/fn3LlzVKxYkaFDh6LVanF3d5fTAKJQyM8xI4Sp0Gg0TJ06lSlTpnD+/Hl0Oh06nY7PPvuM119/Ha1WS926dbl69SoqlYpOnTpx4sQJ3NzcnthWcRwzhaoMbAiLeulf0P9asvcalaytGOThDMCtW7do3749Dx48wGg05vxhMTc3p2fPnnzwwQd069YNS0vLPHl/IQpCfo4ZIUyRSqWiUaNGNGrUiEWLFrF79278/f155513yM7ORqVSYTQaefDgAZ6enpw6dYrq1avn/HxxHTMmeZrA398flUpFiRIlcuatjk5K5YPgcAD0a2cSt2pczutjvh7B7YU9Sdyz/Iltpd2+yO2FPXl45VjOYxl3bpKwaS6+HZtQomRJypcvT61atUhISMi5XcVoNFKiRAkiIyPZunUrvXr1kiIgTFZ+j5m/vB8cTnRSKqtWrUKlUslEWcKkWVpa0qtXL7Zt20ZkZCRWVlY5p3+zs7NJSEjAxcUl55RBXo6Zvx7zaVoVlUr12D+nTp3Kz4/9UkyyDPwlPT2dOXPmADBr2yWynnPO5sHFfWQmxjx3u4a0B5iVqUj5dsNpPeEzDAbDPy7b+ujRI06fPv1y4YVQQH6Nmb9kGYxM/uEA06ZNw8HB4ZWyClGQTp8+TVpa2j8+17p1ayB/xkz5dlq6/HsVJ0+ezPmnXr16uQ9eQEy6DHTt2pV169YRfPAERyP+eOYFHFaOtVFZlCD58JrnbrdE1QbYdp1AKTdPrptXZciYKXTt2hUbGxvMzc2xsbHJea2UAVGY5NeY+Uu2wcjub+fTuFnLnCWPhSgMzpw5k/PvNjY2OWW2YsWKZGRk5NuYMStnzxWjhooudWnevDnNmzc3ySNqJl0GZsyYga2tLVOnzcBM/eyL9dQlymDTvD+p106QHnsl1+9hplZR+Y0B7N69m1atWlGlShWSk5NJTU3lxo0bzJ8//1U/hhAFJr/HzIPLoaRFX6bhoHfyIq4QBWb+/PncuHGD1NRUkpOT+fjjjwHYuHEjFStWzPf9TOAp0767wKTLQJkyZZgzZw43zh3nwc3zz399E2/Mytjyn9Afc7V9o9Hw57wBv17j66+/5ueff+bdd98F/pz5ysXFBQsLi1f5CEIUqPwcM9kPk/nPge8p386PX5JM+qtDiCdYWFjg4uJCyZIlH3s8v/czSXu/5eYnXnw0sCldunTh2LEnr8UxBSY/on3fHIV5OQ3Jh/x53vxIagsrbFoNIT0mnNSIM898LUDSz18TtagXp+b1ZcqUKXz55ZeMHj06r6ILoYj8GjNJe7/GooIj1o26E5WYSla2LDEriob8GDNqq9KUaeKNbdfxVB6ygHId/sXtqGjatWvHzz//nNcf4ZWZfBmIv59JuTbDyNBfJ/XK0ee+3rp+RywqOv/3l/rsLyubFgPRaJdiN+ADeg/yZcKECSxZsiSvoguhiPwYMw+vHCc14gwVuk3889Ys4EF6Vh4nF0IZ+TFmLDWvUaHjW5Sq2YISVeph3aATP27djb29PTNmzMjrj/DKTL4MZGQZKFWnDZaVXyP5cADG7Gd/AanUZpRrM5zMP6J4eOnAM19rbmOHlb0rJV/zYOZHS3jrrbf497//zd27d/PyIwhRoPJ6zBgyHpG07xvKNvbC3LoChrQHGNIekJ6eAUBycjIPHz7Ml88iREHIz/3M35UoXZaePXty8eJFHj169Kqx85TJlwFLczUqlYpynm+SlRzPg/N7nvszpWo2x8rJjeRj6zBmP3nL4NPep2nTpmRlZXHz5s1XjS2EYvJ6zBhS72F4mMy9M9uIXuaT88+e4C08fPiQ8uXLM3To0Pz6OELku4Lcz/x1GsLUZrA1+RkIq9mWRgWUrOZOiWqNSD6+AfOyFZ/7c+Xa+XEncAb3zgY/97Wq/77Pp6GhqNVqXFxcXj24EArJ6zFjZl2eyoMXPPH6+n8c4tjRI+zevZuKFZ+/fSFMVUHtZ2zUGezYsQN3d3dKlCjx6sHzkMmXgdJW5jhXKMXtpFTKt/Mj3n8yGanJWFR89vSOJZzcKOnanEfXn5zpKXH3V6itSmFpXxOz0uWwTL1L/97L2bNnD9OnT6dSpUr59XGEyHd5PWZU5paUqNrgsceq2pbC8fJVzMzMaNeuXV5/BCEKzI0bN9i4cSOk1YXSFfNsP3M3eDHmZSthqamBWcmylM38g47t3uHOnTv4+/vn06d5eSZ/mgDAs5YdZmoVlprXKOXWJtc/V76tFlRPfkQrx9qkx10jae833Nkwh5idK9izZw/Vq1fH2dmZxMTEvIwvRIHL6zHzd2ZqFZ417V41ohCKSUxMZP/+/QD4+Pjwww8/UM3yIWYq8mzMWFaqxqObv5K4+yvubJhD7D5/3NzcOHHiBB07dsyzz5JXVMbn3UdB7tdDfhm5Wcf5+p37dFp2JE/f9+92TWjB1TOH8ff3Z9euXahUKry8vNBqtXTr1k3mGhCFTn6Pmf1T2lDDrky+bV+IvJaZmcnu3bvR6XSEhIRgNBrp0aMHWq2WHj16cPs/6YqNmdzsB19WbvffheLIgGvlMrSuUfG5s0O9KDO1itY1KuLmWIE+ffqwfft2YmNjWbRoETdv3qRXr144OjoyZcoULly4kKfvLUR+yu8xI0VAFBbnz59nypQpODo60qtXL27evMnixYuJjY3lp59+ok+fPlhaWhb7MVMoygDAgj71Mc/jX5K5WsWCPvUfe8zOzo7Jkydz7tw5zp8/j6+vL+vWrcPd3R13d3eWLl1KQkJCnuYQIj8U1JgRwtQkJCSwdOlS3N3dadSoEevWrWPYsGFcuHCBc+fO8fbbb2Nn9+SpruI8ZgpNGahSoRTzvOvm6TY/9K5LlQqlnvp8w4YN+fzzz4mJiSE4OJgaNWowc+ZMHB0d8fb2ZuvWraSnp+dpJiHyihJjRgilpKens2XLFry9vXFwcGDmzJnUqFGDkJAQYmJi+Oyzz2jQoMEzt1Gcx0yhKQMAPh7OTOtcM0+2Nb1zLQZ5PPtK0b9YWFjg5eXF5s2biYuLY9myZej1evr164eDgwMTJkzg7Nmzz53GUoiCptSYEaIgGI1GwsLCmDBhAg4ODvTv3x+9Xs+XX35JfHw8mzdvpmfPni903VdxHTOFqgwATPB0ZWHf+liZq1/43I6ZWoWVuZpP+9ZnvGeNl3p/W1tbxo8fz5kzZwgPD2fUqFFs27YNDw8P6tWrx+LFi4mPj3+pbQuRH5QeM0Lktbi4OBYtWkS9evVo2rQp27Zt41//+hfh4eGcOXOGcePGUaFChZfefnEcM4WuDMCfzW3/lLa0dLEFeO4v66/nW7rYsn9K2zxram5ubnz66adERUWxZ88eGjRowPvvv4+TkxPdunUjKCiItLS0PHkvIV6FqYwZIV7Wo0eP2LBhA926daNKlSp88MEHNGzYkD179hAVFcXChQtxc3PLs/crbmPG5CcdepoqFUoRMLIZ1+/cZ+3pKEKvJRCVmMrfD9SrAGfbUnjWtMO3uXO+Xc1pZmZGly5d6NKlC8nJyWzcuBGdToePjw82Njb4+Pig1Wpp3ry5yU1BKYoPUxozQuSG0Wjk1KlT+Pv7ExQUREpKCi1btuTbb79l4MCB2NjY5Ov7F6cxUyjmGcith+lZRCY+JCPLgKW5mmq2pSltpVzfuXbtGmvWrGHNmjVER0dTs2ZNhg8fzrBhw3B2LlytURRND9Oz6D3sXxhVZnyx9DPFx4wQAFFRUQQEBKDT6bh+/TpVqlRBq9UyfPhwXF1dFc2WH/sZmWcgj5W2Mqeugw2NnMtT18FG8S+1mjVr8tFHHxEZGcn+/ftp1qwZCxYsoFq1anTs2JHAwEBZ7U0oqrSVOSXTEin1KMEkxowovh4+fEhAQAAdO3akWrVqLFiwgObNm3PgwAEiIyOZP3++4kUATG8/k1eKVBkwVWq1mg4dOrBmzRr0ej2rV68mKyuLYcOGodFoGDFiBEeOHMFg+Od1sYUQoigyGAwcPnyYESNGoNFoGD58OFlZWfzwww/o9XrWrFlD+/btUatlV5Xf5P9wAStTpgxvvvkmhw4d4ubNm0ybNo1Dhw7Rtm1batSowbx587h165bSMYUQIt/cvHmTuXPnUqNGDdq1a8fhw4eZPn06N2/e5NChQ/j5+VGmTOE8915YSRlQUPXq1fnggw+IiIjg8OHDeHp6smTJElxcXGjbti0//vgj9+/fVzqmEEK8svv37/PDDz/Qtm1bXnvtNT7//HM8PT05cuQIERERvP/++1SvXl3pmMWWlAEToFaradOmDatXr0av1xMQEIClpSUjR45Eo9EwbNgwDhw4IKcRhBCFisFgYP/+/TmnREeNGoWlpSWBgYE5p0xbt24td1mZACkDJqZ06dL4+vqyb98+bt++zezZszlz5kzORTVz5szh+vXrSscUQoinunbtGrNnz6ZatWp06tSJM2fOMHv2bG7fvs2+ffsYOnQopUqZ/hS9xYmUARNWpUoVZs2axZUrVzhx4gTdu3dn+fLl1KxZk5YtW7Jy5UqSk5OVjimEECQnJ/Pdd9/RsmVLatWqxYoVK+jevTsnT57kypUrzJo1iypVqigdUzyFlIFCQKVS0aJFC7799lvi4+PZsGED5cqVY+zYsWg0GgYPHsyePXvIzs5WOqoQohjJzs5mz549+Pj4oNFoGDduHOXKlWPDhg3o9Xq+/fZbmWytkJAyUMiULFmSQYMGsWvXLqKjo5k/fz4XL17MmaLz3Xff5bffflM6phCiCAsPD2fGjBlUqVKFbt26cfnyZebPn090dDS7du1i0KBBlChRQumY4gVIGSjEHBwcmD59OpcvXyYsLIx+/fqxatUq6tatS9OmTVmxYgWJiYlKxxRCFAGJiYmsWLEiZ1G21atX069fP8LCwrh06RLTp0/HwcFB6ZjiJUkZKAJUKhVNmjThq6++Ii4uji1btmBvb8/kyZOxt7enf//+hISEkJmZqXRUIUQhkpmZSUhICP369cv5TnFwcGDr1q3Ex8fz1Vdf0aRJEzkNUARIGShirKys6Nu3L9u3byc2NpZFixZx48YNvL29cXJyYurUqVy4cEHpmEIIE3bhwgWmTp2Kk5MT3t7e3Lx5k0WLFhEbG8v27dvp06cPlpaWSscUeUjKQBFmZ2fH5MmTOXfuHOfPn2fo0KEEBgbi7u5Oo0aNWLZsGQkJCUrHFEKYgISEBJYtW4a7uzvu7u6sXbuWoUOHcv78ec6dO8fkyZOxs7NTOqbIJ1IGiomGDRvy+eefExsbS3BwMK+99hozZszA0dGRXr16sXXrVjIyMpSOKYQoQOnp6WzduhVvb28cHR159913qVGjBsHBwcTExPD555/TsGFDpWOKAiBloJixsLDAy8uLzZs3Ex8fz7Jly4iLi8s5Jzhx4kTOnj1LLla2FkIUQkajkbNnzzJhwgQcHBzo168fer0+57tg8+bNeHl5YWFhoXRUUYCkDBRjtra2jB8/nrCwMMLDwxk1ahRbtmzBw8OD+vXrs3jxYuLj45WOKYTIA/Hx8SxevJh69erh4eHB1q1bGTVqFOHh4Zw5c4bx48dja2urdEyhECkDAgA3Nzc+/fRToqKi2L17N/Xr1+e9997DycmJ7t27ExQURFpamtIxhRAvIC0tjaCgILp164aTkxPvvfceDRo0YPfu3URFRfHpp5/i5uamdExhAqQMiMeYm5vTtWtX1q9fj16v55tvviE5ORkfHx/s7e0ZM2YMJ0+elNMIQpgoo9HIyZMnGTNmDBqNBh8fH+7du8c333yDXq9n/fr1dO3aFXNzc6WjChMiZUA8Vbly5Xjrrbc4ceIEV69eZfz48ezatYuWLVtSu3ZtFixYQHR0tNIxhRBAdHQ0CxYsoHbt2rRs2ZJdu3YxYcIErl69yvHjx3nrrbcoV66c0jGFiZIyIHKlZs2afPTRR0RGRrJ//36aNm3KRx99RNWqVenUqROBgYGkpqYqHVOIYuXhw4cEBgbSqVMnqlatyscff0yzZs3Yv38/kZGRfPTRR9SsWVPpmKIQkDIgXoharaZDhw4EBARw584dVq9eTUZGRs565SNHjuTIkSNyGkGIfGI0Gjly5AgjR45Eo9EwbNgwMjMzWb16NXq9njVr1tChQwfUavl6F7knf1rESytTpgxvvvkmhw8f5saNG0ydOpXQ0FDatm1LjRo1mDdvHrdu3VI6phBFwq1bt5g3bx6vvfYabdu2JTQ0lGnTpnHjxg0OHTrEm2++SZkyZZSOKQopKQMiT7i4uDB37lwiIiI4fPgw7dq1Y8mSJbi4uNCuXTt+/PFH7t+/r3RMIQqV+/fv8+OPP9KuXTtcXFxYsmQJnp6eHD58mIiICD744ANcXFyUjimKAJO5nPTu3btKRxB5xNXVlY8++ojZs2cTGhpKcHAws2fPZv78+bRv3x5vb28aN24shzFNRMmSJQFkTgkTYTAYOHv2LCEhIRw8eJC0tDSaNm3KqlWr8PT0zPl93blzR+GkIq+Ywv5PZczFyd179+5hY2NDSkoKZcuWzdMAKSkprFixQlbUE0IIUWxZWFgwfvx4bGxs8nS7ud1/K35kwMbGhvHjx8uV6MWE0Wjk0qVLhISEsHfvXh48eECDBg3w8vKiU6dOcs5TAZMnTwZg2bJliuYoju7fv8++ffsIDg7m0qVLWFtb07lzZ7y8vKhfv74sDVyMlCpVKs+LwItQvAzAn4VAyf8JomA5ODjQpUsXHj16RHBwMP7+/kyaNAlLS0t69+6NVqulU6dOmJmZKR21WHj06BEA9vb2CicpHrKzs9m3bx86nY5t27aRmZlJly5dWLp0Kd7e3jmnAYQoSCZRBkTxVLJkSQYNGsSgQYOIi4sjMDAQnU5Ht27dcHBwwNfXF61WK9OliiLht99+Q6fTERAQQHx8PG5ubsyfP5+hQ4fi4OCgdDxRzMkVXMIkODg4MGPGDC5fvkxYWBh9+vRh1apV1K1bl6ZNm7JixQqSkpKUjinEC0lMTGTFihU0bdqUunXrsmrVKvr160dYWBiXL19m+vTpUgSESZAyIEyKSqWiSZMmLF++PGc5VY1Gw9tvv429vT39+/dnx44dcsGpMFmZmZmEhITQv39/7O3tefvtt9FoNGzZsoW4uDi++uormjRpItcDCJMiZUCYLCsrK/r160dwcDCxsbEsXLiQiIgIvLy8cHJyYurUqVy8eFHpmEIAcOHCBaZOnYqTkxPe3t5ERESwaNEi4uLiCA4Opm/fvlhZWSkdU4h/JGVAFAqVK1dmypQpnD9/nnPnzjFkyBACAwNp2LAhjRo1YtmyZSQkJCgdUxQzCQkJLFu2jEaNGuHu7k5gYCBDhw7l/PnznD9/nsmTJ2NnZ6d0TCGeS8qAKHTc3d1ZunQpsbGxBAcH4+LiwowZM3B0dKRXr15s3bqVjIwMpWOKIiojI4OtW7fSq1cvHB0dmTFjBq+99lrOEazPP/+chg0bKh1TiBciZUAUWhYWFnh5ebFlyxbi4+NZtmwZcXFx9OvXDwcHByZOnMgvv/wiiyaJV2Y0Gjl79iwTJ07E3t6efv36ERcXx7Jly4iPj2fz5s14eXlhYWGhdFQhXoqUAVEk2NraMn78+JyrtEeMGMGWLVto0qQJ9evXZ/HixTLdrnhh8fHxLF68mPr16+Ph4cGWLVsYNWoU4eHhhIWFMX78eGxtbZWOKcQrkzIgipy6deuyaNEioqKi2L17N/Xq1eO9997DycmJ7t27ExQURFpamtIxhYlKS0sjKCiI7t274+TkxHvvvUf9+vXZvXs3UVFRfPrppzL3hShypAyIIsvc3JyuXbuyYcMG9Ho9X3/9NcnJyfj4+GBvb8+YMWM4deqUnEYQGI1GTp48yZgxY7C3t8fHx4fk5GS++eYb9Ho969evp2vXrpibyzxtomiSMiCKhXLlyjF69GhOnDjBlStXGDduHLt27aJFixbUrl2bBQsWEB0drXRMUcCio6NZsGABtWvXpmXLluzatYvx48dz9epVTpw4wVtvvUW5cuWUjilEvpMyIIqdWrVq8fHHHxMZGcn+/ftp2rQpH330EVWrVqVTp06sXbtWFs4qwlJTUwkMDKRTp05UrVqVjz/+mGbNmrF//34iIyP56KOPqFmzptIxhShQUgZEsaVWq+nQoQMBAQHcuXOH1atXk5GRga+vLxqNhpEjR3LkyBE5jVAEGI1Gjhw5wsiRI9FoNAwbNozMzExWr16NXq9nzZo1dOjQAbVavhJF8SR/8oUAypQpw5tvvsnhw4e5ceMGU6dOJTQ0lLZt21KjRg3mzZvHrVu3lI4pXtCtW7eYN28er732Gm3btiU0NJR33nmHGzducOjQId58801ZNlsIQGXMxV977t27h42NDSkpKZQtW7YgcgmhOIPBwLFjx/D392fTpk08ePCAtm3botVq6d+/f5HZiXh7ewMQHByscJK8cf/+fTZv3oxOp+Pw4cNYW1szcOBAtFotrVq1kr/9i2Ilt/tvKQNC5MLDhw/ZunUrOp2OgwcPUrJkSfr164efnx/t2rUrdDuYgwcPMmTIELKysrh37x4AZcuWxdzcnHXr1tG+fXuFE74Yg8FAaGgoOp2OLVu28OjRI9q3b4+fnx99+vShdOnSSkcUQhFSBoTIJ1FRUQQEBKDT6bh+/TrOzs4MGzYMrVaLq6ur0vFy5ZdffqFJkyb/+NzZs2dp3LhxASd6OdevX0en0xEQEEBUVBSurq74+fnh6+uLs7Oz0vGEUJyUASHy2V/3put0OoKCgkhJSaFly5b4+fkxcOBAbGxslI74TD169ODnn38mOzsbADMzM7p06cLOnTsVTvZsycnJbNy4EZ1Ox4kTJ7CxsWHQoEH4+fnRvHlzWRpYiL+RMiBEAXr06BHbt29Hp9Oxd+9eLC0t6d27N35+fnTs2BEzMzOlIz7h7NmzeHh4PPZYWFjYU48YKCk7O5t9+/ah0+n46aefyMjIoHPnzvj5+eHt7U3JkiWVjiiESZIyIIRC4uLiCAwMRKfT8dtvv+Hg4ICvry9ardbkprHt0aMHu3fvBqBbt24md1Tgt99+Q6fTERgYSFxcHG5ubvj5+TF06FAcHByUjieEyZMyIITCjEYjv/zyC/7+/qxfv56kpCQ8PDzQarUMHjyYChUqKB3xsaMDpnJUIDExkQ0bNqDT6QgLC6NChQoMGTIErVZL48aN5TSAEC9AyoAQJiQ9PZ0dO3ag0+nYtWsXZmZmeHl54efnR5cuXRRd+rZ27doAXLlyRbEMmZmZ7NmzB51OR3BwMAaDge7du+Pn50ePHj2wsrJSLJsQhZmUASFM1J07d1i3bh06nY4LFy5gZ2fH0KFD8fPzo0GDBgWa5WF6FpF/PCQ924CVuZpqtqUpbVVwi/FcuHABnU7H2rVrSUhIoGHDhvj5+TFkyBDs7OwKLIcQRZWUASEKgfPnz+fsDO/evYu7u3vOzrBSpUr58p7X79xn7ekoQq8mEJWUyt+/AFSAc4VSeNayY2gzZ1wr5/3ESgkJCTll6Pz581SqVImhQ4ei1Wpxd3fP8/cTojiTMiBEIZKZmcnu3bvR6XSEhIRgNBofO0xuaWn5jz/31/DNzXn06KRUZm27xNGIPzBTq8g2PH3o//V86xoVWdCnPlUqlHrmtp+XIyMj47HTJCqVKuc0SdeuXRU9TSJEUSZlQIhCKjExkfXr16PT6Th79iy2trYMHjwYPz8/Xn/99cd2uGPGjOHcuXPs27fvmWNzQ1gUHwSHk2UwPrME/C8ztQpztYp53nXx8fjnSXxSUlLo3LkzjRs35uuvv8553Gg08uuvv+ZcQJmYmEiTJk3w8/PDx8cHW1vbXOcQQrwcKQNCFAHh4eE5t9bFx8dTt25dtFotvr6+lCpVCjs7OzIyMnjjjTfYt2/fP95vvzz0Okv2XnvlLNM612SC5+MzLD569IhOnTpx/PhxLC0tSUhIyFkiWKfTER4ejr29fc4MjaZ2a6UQRZ2UASGKkKysLPbv34+/vz8//fQTmZmZuLm5cfnyZeDP5Zi7dOnC9u3bHzvkviEsiplbL+VZjk/71mfQf48QZGZm0qtXL37++WcMBgMA9erV47fffsPCwoI+ffqg1Wrp2LEj5uYFd1GiEOL/SRkQoohKTk4mKCiIadOm8eDBg5zHVSoVgwYNYu3atajVaqKTUum49DCJv+4lcdeyp26v8uAFWGpqcP+XEB7dOkdmUgzGjDTMy1WmdF1PyjbxRmX+5zULVuZq9k9pi4ONFUOHDmXjxo38/SvE2tqazz77jIEDB1KuXLn8+l8ghMil3O6/pa4LUciUK1eO9u3bP1YE4M9z9Bs2bOCPP/5g3759zNp2iay/XR9g230yFrZOT2zPoqIzWfcSuBe2ndL1PCnbtA8qixKkx4STcmwdabfOYefzESqViiyDkVnbLqHfMIf9+/c/sa0HDx7Qvn17KQJCFDJSBoQohDZv3vyPj6vVan777Teu37nP0Yg/HnvOolJVrOz/eVVFcxsNjmN/QG1ZIuexktUaorIoQXLoD6TH/EaJKnXJNhg5GvEHmbFJqNXqnNMD/5tt5syZr/DphBAFTcqAEIVQz549ycjIwN7eHicnJxwdHXFycqJChQqoVCrmBoc/9/bBv/t7Cfg7K/uaAGTf//9iYaZW4bdwDR94uZGUlERMTAyxsbHExMQQHx9Pjx49Xv0DCiEKlJQBIQqh+vXrU79+/ac+H3o14ckiYDRgNGQ/8VqV+ukrKqbdvgD8eSrhL9kGI6HXEpirqoutrS22trY0bNjwBT+BEMKUSBkQooh5kJ5FVFLqE4/r17zz5ItVaqq+G/yP28lIuMW901spWbMFlnbVH3suKjGVh+lZBTp1sRAi/8hIFqKIuZ34kH86OWDbcyoWtlUef/ApMwZmJd8hYfOHmJWtiG23SU88bwQiEx9S18Hm1QMLIRQnZUCIIiYj68mL+gAsbKs89QLCv8tKSUC/fhYqlZrKPh9jVvKf1yd42vsIIQoftdIBhBB5y9L85Yd1VkoC+nX/BqORykM+wbxsxXx5HyGEaZHRLEQRU822NM9ftuhJ/18EDFQesgBzm6cvIaz67/sIIYoGOU0gRBFT2soc5wqluP0/FxFm3r0N/3A3gXl5ezAaubN+FtkPkrDtPgnDw2TSHybnvMasTMXHjhI425aSiweFKEJkNAtRBHnWsiPg9O3Hbi982pTEFbpNxKKcPVnJ+j9fF/LZE6+xeWMw5VoPBf6cZ8Cz5tOPGgghCh9Zm0CIIuj6nft0WnYk37a/f0obatj984WFQgjTkdv9t1wzIEQR5Fq5DK1rVMRM/TJXDzydmVpF6xoVpQgIUcRIGRCiiFrQpz7meVwGzNUqFvR5+syHQojCScqAEEVUlQqlmOddN0+3+aF3XapUKJWn2xRCKE/KgBBFmI+HM9M618yTbU3vXItBHs7Pf6EQotCRuwmEKOImeLpS0dqKD4LDyTIYc72SIfx5jYC5WsWH3nWlCAhRhMmRASGKAR8PZ/ZPaUtLF1uA515Y+NfzLV1s2T+lrRQBIYo4OTIgRDFRpUIpAkY24/qd+6w9HUXotQSiElMfW9RIxZ8TCnnWtMO3ubPcNSBEMSHzDAhRjD1MzyIy8SEZWQYszdVUsy0tMwsKUYTkdv8to16IYqy0lbksQyyEkGsGhBBCiOJOyoAQQghRzEkZEEIIIYo5KQNCCCFEMSdlQAghhCjmpAwIIYQQxZyUASGEEKKYkzIghBBCFHNSBoQQQohiTsqAEEIIUcxJGRBCCCGKOSkDQgghRDEnZUAIIYQo5qQMCCGEEMWclAEhhBCimJMyIIQQQhRz5rl5kdFoBODevXv5GkYIIYQQeeev/fZf+/GnyVUZuH//PgBVqlR5xVhCCCGEKGj379/Hxsbmqc+rjM+rC4DBYCAuLo4yZcqgUqnyNKAQQggh8ofRaOT+/fs4ODigVj/9yoBclQEhhBBCFF1yAaEQQghRzEkZEEIIIYo5KQNCCCFEMSdlQAghhCjmpAwIIYQQxZyUASGEEKKYkzIghBBCFHP/ByvRyFcJw627AAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "G2 = nx.DiGraph([('E'+str(u), 'NN'+str(v)) for u,v in zip(*model.ResBlocks[0].lin1.indices.detach().numpy())] + [('NN'+str(u),'E'+str(v)) for u,v in zip(*model.ResBlocks[0].lin3.indices.detach().numpy())]) \n", "\n", "fig, ax = plt.subplots()\n", "nx.draw_networkx(G2, pos={'E1': (0,0),\n", " 'NN0': (-1,-1), 'NN1':(0,-1), 'NN2':(1,-1),\n", " 'E0':(0,-2),\n", " 'NN3':(-1,-3), 'NN4':(0,-3), 'NN5':(1,-3),\n", " 'E2':(0,-4)}, ax=ax) \n", "\n", "ax.add_patch(patches.Rectangle((-1.1, -1.5), 2.2, 1, linewidth=1, edgecolor='gray', facecolor='none'))\n", "ax.add_patch(patches.Rectangle((-1.1, -3.5), 2.2, 1, linewidth=1, edgecolor='gray', facecolor='none'))\n", "\n", "plt.show()\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "gsnn-lib", "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.12.8" } }, "nbformat": 4, "nbformat_minor": 2 }