You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@singa.apache.org by wa...@apache.org on 2017/08/04 08:32:45 UTC

[01/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Repository: incubator-singa
Updated Branches:
  refs/heads/master e5c438c34 -> 0f86cd5a3


SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/8c9b594b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/8c9b594b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/8c9b594b

Branch: refs/heads/master
Commit: 8c9b594ba566ed1fe865fd7ec6360523cce706e5
Parents: c94b3df
Author: Moaz Reyad <mo...@gmail.com>
Authored: Thu Jun 22 13:56:16 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:15:59 2017 +0800

----------------------------------------------------------------------
 doc/en/docs/notebook/rnn.ipynb | 317 ++++++++++++++++++++++++++++++------
 python/setup.py.in             |   5 +-
 2 files changed, 269 insertions(+), 53 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/8c9b594b/doc/en/docs/notebook/rnn.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/rnn.ipynb b/doc/en/docs/notebook/rnn.ipynb
index 054ac19..f05c5b6 100644
--- a/doc/en/docs/notebook/rnn.ipynb
+++ b/doc/en/docs/notebook/rnn.ipynb
@@ -18,15 +18,23 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {
-    "collapsed": true
-   },
+   "execution_count": 1,
+   "metadata": {},
    "outputs": [],
    "source": [
-    "import cPickle as pickle\n",
+    "from __future__ import division\n",
+    "from __future__ import print_function\n",
+    "from future import standard_library\n",
+    "standard_library.install_aliases()\n",
+    "from builtins import zip\n",
+    "from builtins import range\n",
+    "from builtins import object\n",
+    "from past.utils import old_div\n",
+    "import pickle as pickle\n",
     "import numpy as np\n",
     "import argparse\n",
+    "import sys\n",
+    "from tqdm import tnrange, tqdm_notebook\n",
     "\n",
     "# sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))\n",
     "from singa import layer\n",
@@ -36,12 +44,12 @@
     "from singa import optimizer\n",
     "from singa import initializer\n",
     "from singa.proto import model_pb2\n",
-    "from tqdm import tnrange"
+    "from singa import utils"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 2,
    "metadata": {
     "collapsed": true
    },
@@ -51,6 +59,7 @@
     "\n",
     "    def __init__(self, fpath, batch_size=32, seq_length=100, train_ratio=0.8):\n",
     "        '''Data object for loading a plain text file.\n",
+    "\n",
     "        Args:\n",
     "            fpath, path to the text file.\n",
     "            train_ratio, split the text file into train and test sets, where\n",
@@ -63,19 +72,22 @@
     "        self.idx_to_char = {i: ch for i, ch in enumerate(chars)}\n",
     "        data = [self.char_to_idx[c] for c in self.raw_data]\n",
     "        # seq_length + 1 for the data + label\n",
-    "        nsamples = len(data) / (1 + seq_length)\n",
+    "        nsamples = old_div(len(data), (1 + seq_length))\n",
     "        data = data[0:nsamples * (1 + seq_length)]\n",
     "        data = np.asarray(data, dtype=np.int32)\n",
     "        data = np.reshape(data, (-1, seq_length + 1))\n",
     "        # shuffle all sequences\n",
     "        np.random.shuffle(data)\n",
     "        self.train_dat = data[0:int(data.shape[0]*train_ratio)]\n",
-    "        self.num_train_batch = self.train_dat.shape[0] / batch_size\n",
+    "        self.num_train_batch = old_div(self.train_dat.shape[0], batch_size)\n",
     "        self.val_dat = data[self.train_dat.shape[0]:]\n",
-    "        self.num_test_batch = self.val_dat.shape[0] / batch_size\n",
-    "        print 'train dat', self.train_dat.shape\n",
-    "        print 'val dat', self.val_dat.shape\n",
-    "        \n",
+    "        self.num_test_batch = old_div(self.val_dat.shape[0], batch_size)\n",
+    "        self.batch_size = batch_size\n",
+    "        self.seq_length = seq_length\n",
+    "        print('train dat', self.train_dat.shape)\n",
+    "        print('val dat', self.val_dat.shape)\n",
+    "\n",
+    "\n",
     "def numpy2tensors(npx, npy, dev):\n",
     "    '''batch, seq, dim -- > seq, batch, dim'''\n",
     "    tmpx = np.swapaxes(npx, 0, 1)\n",
@@ -108,26 +120,47 @@
    "cell_type": "markdown",
    "metadata": {},
    "source": [
+    "Prepare the dataset. Download [all works of Shakespeare concatenated](http://cs.stanford.edu/people/karpathy/char-rnn/shakespeare_input.txt). Other plain text files can also be used. "
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
     "## Create the network"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": false
-   },
-   "outputs": [],
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "train dat (36224, 101)\n",
+      "val dat (9056, 101)\n",
+      "dense w  (32, 67)\n",
+      "dense b  (67,)\n",
+      "dense weight l1 = 0.154445\n",
+      "dense b l1 = 0.000000\n"
+     ]
+    }
+   ],
    "source": [
-    "\n",
     "def get_lr(epoch):\n",
-    "    return 0.001 / float(1 << (epoch / 50))\n",
+    "    return old_div(0.001, float(1 << (old_div(epoch, 50))))\n",
+    "\n",
+    "hidden_size=32\n",
+    "num_stacks=1\n",
+    "dropout=0.5\n",
     "\n",
-    "data = Data('static/linux_input.txt')\n",
+    "data = Data('static/shakespeare_input.txt')\n",
     "# SGD with L2 gradient normalization\n",
     "opt = optimizer.RMSProp(constraint=optimizer.L2Constraint(5))\n",
     "cuda = device.create_cuda_gpu()\n",
-    "rnn = layer.LSTM(name='lstm', hidden_size=32, num_stacks=1, dropout=0.5, input_sample_shape=(data.vocab_size,))\n",
+    "rnn = layer.LSTM(name='lstm', hidden_size=hidden_size, num_stacks=num_stacks, dropout=dropout, input_sample_shape=(data.vocab_size,))\n",
     "rnn.to_device(cuda)\n",
     "rnn_w = rnn.param_values()[0]\n",
     "rnn_w.uniform(-0.08, 0.08)  \n",
@@ -136,16 +169,15 @@
     "dense.to_device(cuda)\n",
     "dense_w = dense.param_values()[0]\n",
     "dense_b = dense.param_values()[1]\n",
-    "print 'dense w ', dense_w.shape\n",
-    "print 'dense b ', dense_b.shape\n",
+    "print('dense w ', dense_w.shape)\n",
+    "print('dense b ', dense_b.shape)\n",
     "initializer.uniform(dense_w, dense_w.shape[0], 0)\n",
-    "print 'dense weight l1 = %f' % (dense_w.l1())\n",
+    "print('dense weight l1 = %f' % (dense_w.l1()))\n",
     "dense_b.set_value(0)\n",
-    "print 'dense b l1 = %f' % (dense_b.l1())\n",
+    "print('dense b l1 = %f' % (dense_b.l1()))\n",
     "\n",
     "g_dense_w = tensor.Tensor(dense_w.shape, cuda)\n",
-    "g_dense_b = tensor.Tensor(dense_b.shape, cuda)\n",
-    "\n"
+    "g_dense_b = tensor.Tensor(dense_b.shape, cuda)"
    ]
   },
   {
@@ -157,19 +189,72 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "f97e3eae043e4cafb09b9860af94ef3c"
+      }
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\n",
+      "Epoch 0, train loss is 2.722489\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "b614c1d388d94b839723aaf8272e968f"
+      }
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\n",
+      "Epoch 1, train loss is 4.940666\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "77878ccc79ab444d9b5d7bb9cc3b95dd"
+      }
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "\n",
+      "Epoch 2, train loss is 7.043295\n"
+     ]
+    }
+   ],
    "source": [
     "lossfun = loss.SoftmaxCrossEntropy()\n",
     "train_loss = 0\n",
     "for epoch in range(3):\n",
     "    bar = tnrange(data.num_train_batch, desc='Epoch %d' % 0)\n",
     "    for b in bar:\n",
-    "        batch = data.train_dat[b * batch_size: (b + 1) * batch_size]\n",
-    "        inputs, labels = convert(batch, batch_size, seq_length, data.vocab_size, cuda)\n",
+    "        batch = data.train_dat[b * data.batch_size: (b + 1) * data.batch_size]\n",
+    "        inputs, labels = convert(batch, data.batch_size, data.seq_length, data.vocab_size, cuda)\n",
     "        inputs.append(tensor.Tensor())\n",
     "        inputs.append(tensor.Tensor())\n",
     "\n",
@@ -183,13 +268,13 @@
     "            lvalue = lossfun.forward(model_pb2.kTrain, act, label)\n",
     "            batch_loss += lvalue.l1()\n",
     "            grad = lossfun.backward()\n",
-    "            grad /= batch_size\n",
+    "            grad /= data.batch_size\n",
     "            grad, gwb = dense.backward(model_pb2.kTrain, grad)\n",
     "            grads.append(grad)\n",
     "            g_dense_w += gwb[0]\n",
     "            g_dense_b += gwb[1]\n",
     "            # print output.l1(), act.l1()\n",
-    "            bar.set_postfix(train_loss=batch_loss / seq_length)\n",
+    "            bar.set_postfix(train_loss=old_div(batch_loss, data.seq_length))\n",
     "        train_loss += batch_loss\n",
     "\n",
     "        grads.append(tensor.Tensor())\n",
@@ -199,8 +284,7 @@
     "        opt.apply_with_lr(epoch, get_lr(epoch), g_rnn_w, rnn_w, 'rnnw')\n",
     "        opt.apply_with_lr(epoch, get_lr(epoch), g_dense_w, dense_w, 'dense_w')\n",
     "        opt.apply_with_lr(epoch, get_lr(epoch), g_dense_b, dense_b, 'dense_b')\n",
-    "    print '\\nEpoch %d, train loss is %f' % (epoch, train_loss / data.num_train_batch / seq_length)\n",
-    "\n"
+    "    print('\\nEpoch %d, train loss is %f' % (epoch, train_loss / data.num_train_batch / data.seq_length))"
    ]
   },
   {
@@ -212,14 +296,22 @@
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
-   "outputs": [],
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "saving model to static/model_2.bin\n"
+     ]
+    }
+   ],
    "source": [
-    "with open('%s_%d.bin' % (model_path, epoch), 'wb') as fd:\n",
-    "    print 'saving model to %s' % model_path\n",
+    "model_path= 'static/model_' + str(epoch) + '.bin'\n",
+    "\n",
+    "with open(model_path, 'wb') as fd:\n",
+    "    print('saving model to %s' % model_path)\n",
     "    d = {}\n",
     "    for name, w in zip(['rnn_w', 'dense_w', 'dense_b'],[rnn_w, dense_w, dense_b]):\n",
     "        d[name] = tensor.to_numpy(w)\n",
@@ -228,28 +320,149 @@
     "    d['hidden_size'] = hidden_size\n",
     "    d['num_stacks'] = num_stacks\n",
     "    d['dropout'] = dropout\n",
-    "    pickle.dump(d, fd)"
+    "    pickle.dump(d, fd)\n",
+    "fd.close()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Sample"
    ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Before we proceed any further, hear me speak.\n",
+      "\n",
+      "BRANCANBHAND:\n",
+      "But yey toor ssen!\n",
+      "\n",
+      "CRROSLA:\n",
+      "Ony chorsery,\n",
+      "I sty hit to ruse's\n",
+      "'bae\n",
+      "As bit.\n",
+      "Hew, sfohmzero nitl\n",
+      "No Wimen;\n",
+      "A astherter!\n",
+      "\n",
+      "CAORTEUS:\n",
+      "Dodt;\n",
+      "Wighble a cavinn a nooms;\n",
+      "Pepeif,\n",
+      "That by peryer,\n",
+      "Cisher jay thay ro ou hough me me awow, and fer,\n",
+      "Got thy\n",
+      "zith shone sort in and kides Eok spand.\n",
+      "\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "nsamples  = 300\n",
+    "seed_text = \"Before we proceed any further, hear me speak.\"\n",
+    "do_sample = True\n",
+    "\n",
+    "with open(model_path, 'rb') as fd:\n",
+    "        d = pickle.load(fd)\n",
+    "        rnn_w = tensor.from_numpy(d['rnn_w'])\n",
+    "        idx_to_char = d['idx_to_char']\n",
+    "        char_to_idx = d['char_to_idx']\n",
+    "        vocab_size = len(idx_to_char)\n",
+    "        dense_w = tensor.from_numpy(d['dense_w'])\n",
+    "        dense_b = tensor.from_numpy(d['dense_b'])\n",
+    "        hidden_size = d['hidden_size']\n",
+    "        num_stacks = d['num_stacks']\n",
+    "        dropout = d['dropout']\n",
+    "\n",
+    "rnn = layer.LSTM(name='lstm', hidden_size=hidden_size,\n",
+    "                     num_stacks=num_stacks, dropout=dropout,\n",
+    "                     input_sample_shape=(len(idx_to_char),))\n",
+    "rnn.to_device(cuda)\n",
+    "rnn.param_values()[0].copy_data(rnn_w)\n",
+    "dense = layer.Dense('dense', vocab_size, input_sample_shape=(hidden_size,))\n",
+    "dense.to_device(cuda)\n",
+    "dense.param_values()[0].copy_data(dense_w)\n",
+    "dense.param_values()[1].copy_data(dense_b)\n",
+    "hx = tensor.Tensor((num_stacks, 1, hidden_size), cuda)\n",
+    "cx = tensor.Tensor((num_stacks, 1, hidden_size), cuda)\n",
+    "hx.set_value(0.0)\n",
+    "cx.set_value(0.0)\n",
+    "if len(seed_text) > 0:\n",
+    "    for c in seed_text:\n",
+    "        x = np.zeros((1, vocab_size), dtype=np.float32)\n",
+    "        x[0, char_to_idx[c]] = 1\n",
+    "        tx = tensor.from_numpy(x)\n",
+    "        tx.to_device(cuda)\n",
+    "        inputs = [tx, hx, cx]\n",
+    "        outputs = rnn.forward(model_pb2.kEval, inputs)\n",
+    "        y = dense.forward(model_pb2.kEval, outputs[0])\n",
+    "        y = tensor.softmax(y)\n",
+    "        hx = outputs[1]\n",
+    "        cx = outputs[2]\n",
+    "    sys.stdout.write(seed_text)\n",
+    "else:\n",
+    "    y = tensor.Tensor((1, vocab_size), cuda)\n",
+    "    y.set_value(old_div(1.0, vocab_size))\n",
+    "\n",
+    "for i in range(nsamples):\n",
+    "    y.to_host()\n",
+    "    prob = tensor.to_numpy(y)[0]\n",
+    "    if do_sample:\n",
+    "        cur = np.random.choice(vocab_size, 1, p=prob)[0]\n",
+    "    else:\n",
+    "        cur = np.argmax(prob)\n",
+    "    sys.stdout.write(idx_to_char[cur])\n",
+    "    x = np.zeros((1, vocab_size), dtype=np.float32)\n",
+    "    x[0, cur] = 1\n",
+    "    tx = tensor.from_numpy(x)\n",
+    "    tx.to_device(cuda)\n",
+    "    inputs = [tx, hx, cx]\n",
+    "    outputs = rnn.forward(model_pb2.kEval, inputs)\n",
+    "    y = dense.forward(model_pb2.kEval, outputs[0])\n",
+    "    y = tensor.softmax(y)\n",
+    "    hx = outputs[1]\n",
+    "    cx = outputs[2]\n",
+    "print('')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
   "anaconda-cloud": {},
   "kernelspec": {
-   "display_name": "Python [conda env:conda]",
+   "display_name": "py3",
    "language": "python",
-   "name": "conda-env-conda-py"
+   "name": "py3"
   },
   "language_info": {
    "codemirror_mode": {
     "name": "ipython",
-    "version": 2
+    "version": 3
    },
    "file_extension": ".py",
    "mimetype": "text/x-python",
    "name": "python",
    "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.13"
+   "pygments_lexer": "ipython3",
+   "version": "3.5.3"
   }
  },
  "nbformat": 4,

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/8c9b594b/python/setup.py.in
----------------------------------------------------------------------
diff --git a/python/setup.py.in b/python/setup.py.in
index 044710f..97ea2ca 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -66,7 +66,10 @@ setup(
         'flask>=0.10.1',
         'flask_cors>=3.0.2',
         'pillow>=2.3.0',
-        'future'
+        'future',
+	'xmlrunner',
+	'tqdm',
+	'ipywidgets',
         ],
 
     #List additional groups of dependencies here (e.g. development


[06/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/doc/en/docs/notebook/rbm.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/rbm.ipynb b/doc/en/docs/notebook/rbm.ipynb
index c9aadf5..fd3309c 100755
--- a/doc/en/docs/notebook/rbm.ipynb
+++ b/doc/en/docs/notebook/rbm.ipynb
@@ -18,19 +18,25 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {
-    "collapsed": false
-   },
+   "execution_count": 1,
+   "metadata": {},
    "outputs": [],
    "source": [
+    "from __future__ import division\n",
+    "from __future__ import print_function\n",
+    "from future import standard_library\n",
+    "standard_library.install_aliases()\n",
+    "standard_library.install_aliases()\n",
+    "from builtins import range\n",
+    "from past.utils import old_div\n",
+    "\n",
     "import numpy as np\n",
     "import os\n",
     "import gzip\n",
     "import argparse\n",
-    "import cPickle\n",
+    "import pickle\n",
     "import utils\n",
-    "import urllib\n",
+    "import urllib.request, urllib.parse, urllib.error\n",
     "from PIL import Image\n",
     "\n",
     "import matplotlib.pyplot as plt\n",
@@ -39,14 +45,14 @@
     "\n",
     "def load_train_data():\n",
     "    # download the data for the first time running\n",
-    "    print 'downloading data'\n",
-    "    urllib.urlretrieve('https://github.com/mnielsen/neural-networks-and-deep-learning/raw/master/data/mnist.pkl.gz', 'data.bin')\n",
-    "    print 'finished data downloading'\n",
+    "    print('downloading data')\n",
+    "    urllib.request.urlretrieve('https://github.com/mnielsen/neural-networks-and-deep-learning/raw/master/data/mnist.pkl.gz', 'data.bin')\n",
+    "    print('finished data downloading')\n",
     "    f = gzip.open('data.bin', 'rb')\n",
-    "    train_set, valid_set, test_set = cPickle.load(f)\n",
+    "    train_set, valid_set, test_set = pickle.load(f, encoding='latin1')\n",
     "    traindata = train_set[0].astype(np.float32)\n",
     "    validdata = valid_set[0].astype(np.float32)\n",
-    "    print traindata.shape, validdata.shape\n",
+    "    print(traindata.shape, validdata.shape)\n",
     "    return traindata, validdata"
    ]
   },
@@ -59,7 +65,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 2,
    "metadata": {
     "collapsed": true
    },
@@ -68,7 +74,7 @@
     "from singa import initializer\n",
     "from singa import optimizer\n",
     "from singa import device\n",
-    "from singa import tensor\n"
+    "from singa import tensor"
    ]
   },
   {
@@ -85,10 +91,8 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {
-    "collapsed": false
-   },
+   "execution_count": 3,
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -111,7 +115,7 @@
     "vb = tensor.from_numpy(np.zeros(vdim, dtype = np.float32))\n",
     "hb = tensor.from_numpy(np.zeros(hdim, dtype = np.float32))\n",
     "\n",
-    "print 'Loading data ..................'\n",
+    "print('Loading data ..................')\n",
     "dat,_ = load_train_data()\n",
     "\n",
     "use_gpu = False\n",
@@ -121,7 +125,7 @@
     "    dev = device.get_default_device()\n",
     "\n",
     "for t in [w, vb, hb]:\n",
-    "    t.to_device(dev)   "
+    "    t.to_device(dev)"
    ]
   },
   {
@@ -140,32 +144,32 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 4,
    "metadata": {
-    "collapsed": false
+    "scrolled": false
    },
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "Epoch 0, Reconstruction error per image = 17.989441\n",
-      "Epoch 1, Reconstruction error per image = 10.955967\n",
-      "Epoch 2, Reconstruction error per image = 9.593508\n",
-      "Epoch 3, Reconstruction error per image = 8.900522\n",
-      "Epoch 4, Reconstruction error per image = 8.485637\n",
-      "Epoch 5, Reconstruction error per image = 8.187351\n",
-      "Epoch 6, Reconstruction error per image = 7.981121\n",
-      "Epoch 7, Reconstruction error per image = 7.825888\n",
-      "Epoch 8, Reconstruction error per image = 7.707948\n",
-      "Epoch 9, Reconstruction error per image = 7.589963\n"
+      "Epoch 0, Reconstruction error per image = 17.919702\n",
+      "Epoch 1, Reconstruction error per image = 10.966256\n",
+      "Epoch 2, Reconstruction error per image = 9.598818\n",
+      "Epoch 3, Reconstruction error per image = 8.899601\n",
+      "Epoch 4, Reconstruction error per image = 8.476742\n",
+      "Epoch 5, Reconstruction error per image = 8.188001\n",
+      "Epoch 6, Reconstruction error per image = 7.974924\n",
+      "Epoch 7, Reconstruction error per image = 7.822625\n",
+      "Epoch 8, Reconstruction error per image = 7.691377\n",
+      "Epoch 9, Reconstruction error per image = 7.588384\n"
      ]
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAQUAAAD8CAYAAAB+fLH0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzsvGdUlPfW/v8Z6jAwQ+9laFJEOoKCohGxYY1E1Fii0aiJ\n6eUknuQcU0xOEk9iTHL0xBg10WjsmkgQQRAQpAnSe5FehzIDzFDm/yL/3Ov3vHj+v7x4sv7nWcvr\n3bDuNffMl9n73vva17VFWq2WR3iER3iE36Hz//cHeIRHeIT/LDxKCo/wCI/wX/AoKTzCIzzCf8Gj\npPAIj/AI/wWPksIjPMIj/Bc8SgqP8AiP8F/wpyUFkUi0RCQSVYtEojqRSPTmn3WfR3iER/ifhejP\n0CmIRCJdoAaIBVqBfGCDVqut+B+/2SM8wiP8j+LPqhTCgTqtVtug1Wo1wDlg1Z90r0d4hEf4H4Te\nn/S+jkDL//G6FYj47y42MTHRarVaLC0tEYvFaDQahoaG0NfXx8TEhM7OTkxNTZFKpRgZGdHR0YG5\nuTljY2NoNBo0Gg02NjaoVCoMDAxQqVR0dHRgamqKoaEhenp6jIyM4ODggEqlwsjICJVKxcjICLa2\ntgwPD2NsbEx3dzf6+vqYmpry8OFDrKysmJycxMLCgq6uLgwMDGhvb8fV1VW43t7entbWVuF9RCIR\no6OjKBQK/Pz8UCqVaLVaRCIRAwMDSKVSRkdHMTMzQ6VSMTo6ip6eHt3d3Tg7O2NoaIi+vj79/f2I\nxWLGxsYwMDBAKpWio6PD+Pg4AFqtlr6+PszMzJiamsLAwACFQoFYLMbQ0BCNRsPY2Jjw3Y2MjNDT\n08PAwIDm5mbEYjFGRkbCPcbHx5FKpahUKsbGxjAzM2NycpLx8XFEIhEymQyFQoGuri46OjrC/2Zo\naAilUomTkxMqlQpdXV309PTo6+vDysqKgYEBzMzMG
 B4eBqCrq4tp06YxNDSEmZkZRkZGKBQK+vv7\nGRwcxMvLC4Dx8XF0dHTQaDTC51er1UxOTmJsbIy+vj7j4+Po6+szNTWFvr4+urq69Pb2YmZmhlqt\nRq1WIxKJ6OrqwsHBAbFYjLGxMX19fWg0GqysrFAoFFhZWWFgYEBPTw9arRZDQ0MMDAwYGxtDIpEI\n56xSqZBIJExMTKBQKFAoFDg4ODA2NoaVlRX6+vp0dHQgk8nQ09NjYmICrVaLSqVCLBbT09ODXC5H\nrVYzNjaGVCqlrq4OGxsbAHR0dDA3N6eyshI7OztUKhVSqZSpqSnUajXGxsbC3xQKBYaGhkilUpRK\nJRMTE0gkEqamptDV1QVgZGQEfX19RCIRurq6tLW19Wq1Wuv/W/D+WUnh/wqRSPQM8AyAra0tH374\nIa6urmRlZXHx4kW2bt2Kvb09Pj4+pKSksGDBAsrKyli5ciWFhYUEBwdz5MgRampqOHjwIMnJyRQU\nFCCVSunq6uL8+fPcvHmTDRs2sG/fPs6fP09kZCRhYWFcvnyZhQsXcvfuXYaGhoiMjOT27dt4e3sz\nY8YM9PT0kEql3L9/H11dXerr65k/fz737t3j8OHDJCYmcubMGXR0dFiwYAFZWVl0dXURHx/PxYsX\n6ezsJC8vj+PHj3P69GkKCgqYNWsWoaGh3Lp1i4SEBDIzM9FoNLz++uuUlJSwcOFCXnjhBdrb27Gw\nsGDp0qWIxWLu37/P7Nmzyc7OxsXFhaKiIh5//HFu3bqFiYkJw8PDyGQyHj58iFQqpaioiKCgILRa\nLXPmzOHmzZs0NzczNTXFhg0b+OWXX/Dy8qKiooLq6mqeeOIJMjMzmTt3LuXl5URFRVFaWkpFRQWO\njo6EhISQlZWFWq3GxcUFqVRKaWkp4eHh7N+/n08++YSWlhb8/f159tlnWblyJbq6uixZsoRz584h\nk8mQyWQ4ODiQn5/PkSNH2LJl
 C8HBwTQ0NFBTU0NAQABRUVHs3LmTEydOcPr0aWxtbZk7dy4jIyN0\ndnaiUCj47LPPeOaZZ3jyySe5ePEi06dPp7Kykrlz59LT08Ps2bN59913mTNnDr29vYyPj/P5558D\nsGHDBjZt2oSjoyMDAwN8+eWXiMViLCwsKCwsxM3NjaioKAYHB0lMTGTfvn2kpqYyOTnJ7du3WbJk\nCdXV1QQGBhIcHMz4+DhRUVG8+uqrtLe3M2/ePN577z2io6NJSUnhpZdeIigoiNLSUjw8PLh27Rpv\nvvkmFRUVFBYWoq+vT2trK25ubjz11FPIZDJOnTpFQEAAf/vb34iPj8fAwIDIyEiMjIyor6+nqamJ\nqakpXFxcuH//vpDU0tPTeeGFFzAyMmJ0dBSpVMrw8DD29vb09/dz+/Zt7O3t+frrr5v/SGz+We1D\nG+D8f7x2+n//JkCr1X6j1WrDtFptmJmZGc3Nzejp6REREcFbb72FnZ0dg4ODVFRUIJVKKS8v5+WX\nX2Z4eBiVSsWPP/6Iq6sr+/btY968edjZ2aGj89vX8fX1BeDkyZM0NjYyPDzMJ598gqOjI3Z2djz5\n5JMAGBoa8t5776Gnp8f06dOxsbHB0dERsVjM8ePHqa+vp6WlBTMzM9ra2ggODgbg559/Zu3atdja\n2tLR0UFjYyNOTk50dnbi7++PoaEhP/30EzU1Nbi6uuLu7s7OnTsZHx/n+eefp7a2lqioKFpaWrh4\n8aKQ2RMSEujr6yMuLg6VSoVarSYlJYXx8XHMzc2pq6sjNjaWiooKPDw8GBkZQVdXl+rqary9vVGp\nVLi5uWFjY4ONjQ13796ltraW3NxcVCoVV69eJT09neHhYTo7O/noo4+4ffs2c+fO5datWzg7O1Na\nWsrg4CBlZWVMTExgZmaGq6srLi4u6OrqUl5ejkgkwsjIiDfeeIPS0lI0Gg1paWmsWbMGiUSCWCym\nu7sbuVy
 ORCLB29ubvr4+LC0tyc3NZffu3XR1dTF//nymTZuGubk5JiYmAELV8vPPP2NgYIClpSUd\nHR3U1tYSHR2Nrq4ud+/eZdq0aeTm5uLk5ERlZSUODg40Nzfj6+tLXl4ezc3N2NnZ8euvvwLg6urK\nzZs3yc/PR6VS8cYbbxASEsLrr79OVVUVk5OT1NfXk5mZycaNGzE1NSUvL4/h4WHWrVuHWCxGqVSy\naNEiioqKOHPmDABhYWF88sknNDc387e//Y3Q0FDKy8uJi4tDV1eXefPmMWvWLJ577jkyMjIYHBxk\n586d6OjosG/fPvbu3cvQ0BCenp48/fTTlJSUANDa2kpzczPZ2dmcOHGC/Px8rK2tCQkJobm5mbKy\nMlJSUrCysmLz5s20tbVRUlJCWVkZzzzzDN3d3ZSVlVFQUCCc8R/Fn5UU8oFpIpHITSQSGQDrgev/\n3cX9/f0olUo0Gg3j4+O89dZbjI2N4eHhQXBwMIsXLyYoKIitW7eSmppKeno6g4ODDA0NodVqefbZ\nZykrK2PdunWMj48L5ZilpSXHjx/HwcGBlpYW3NzcuHLlCu7u7rS2tjJ9+nSamprYuXMnxcXFSCQS\nhoeHcXBw4ODBg1haWrJt2zb09fXx9/fno48+AmDevHl0dnaSnZ0NwPr16/Hz86OgoIDGxkacnZ05\nf/48x44d48yZMzg6OnLs2DF8fX05c+YMfn5+SCQSbG1tWbBggXAOhYWFBAUF0djYCICPjw+bNm0i\nPT0dR0dHxsbGmJiYICgoiKqqKq5du4ZarSYwMBCFQoGbmxuPPfYYAwMDNDY2Mn/+fO7fv8/OnTvx\n8PDAwsKC+Ph4KioqCAwMJDc3FwcHBxoaGmhvb+fy5ctUVlYyMjKCu7s7ly9fJjs7m6mpKezt7Zk1\naxYJCQloNBr6+/vp6+sjLS0NHx8f+vv7OXDgADU1NdjY2NDY2IinpycajYbc3FyWLVtG
 ZmYm9vb2\nPPPMM8jlcubOncv+/ft5/PHHWbp0qXAGcXFxzJ49m1OnTnHixAkmJycxNzdn+/bteHl5UVxczMOH\nD3FxcUGhUKDVavniiy/4+uuv6e3tZdu2bUilUh48eEBpaSkAhw4dwtramt7eXnp6ehgYGMDZ2Zm0\ntDQWLFiAWCzGxMSExx9/nK6uLm7duoVcLic9PZ2ysjL6+/sJDg7m4MGDODk5ERoaCoBareaZZ57h\n5s2bODs7c/nyZb7//ns+/vhjHjx4gI6ODidPnuTmzZuo1WrCw8N59tln2bx5M3fv3sXS0hI7Ozu6\nu7sxMjLi2LFjQkzo6+sjkUjw8fFBKpXS29vLgwcPcHR05LnnnmPt2rU8ePAAZ2dnHj58yNWrV3nq\nqadYvXo106ZNw97envHxcWJjY/niiy/+cPD+KUlBq9VOAHuBm0AlcF6r1Zb/d9dLJBImJyfp6OhA\nq9USHBxMeHg4Pj4+HDx4kNLSUsbGxoTMu2jRInJycpg5cyaDg4P4+/uTlZXFzz//jEQiEZLC2NgY\nFRUVeHp6olQq6e3txc/Pj76+PgwMDDA0NCQ9PZ2EhAT27duHj48POjo6pKenC6Xc9evXmZiYoK2t\njcLCQuC3vtjGxoaXXnqJjIwM9PX1efDgAaGhoXh7e6Onp4eFhYWQsQMCAvjwww+5evUqERERWFlZ\n0drayowZM7hw4QI9PT0ANDY2otFoKCsrQ0dHh+zsbLq7u1Gr1bi7u7NgwQLS09M5dOgQbm5unD9/\nnvHxce7du8e8efOIiYmhrq4OsViMu7s7J0+eZOXKleTm5hIdHY2LiwtJSUksX74ctVpNXl4eU1NT\n1NfXMzk5ybZt21i2bBne3t7o6+vzzjvvoFarsbKyYmhoiIqKCtavX49cLmd4eJgdO3bw0UcfoVAo\nMDMz47PPPsPc3BypVMquXbv44YcfmD17NuXl5ezatYtZs2bx4os
 vEhMTg4WFBZWVlSQlJSESiTh1\n6hQAxsbGJCYm4uHhQUJCAosWLcLd3Z2VK1dy9OhR2traePHFF2lqasLFxQUXFxfi4uKQy+UYGRlh\nZ2dHdXU1Y2NjrF69GgsLCwBee+01ampqhHawtLSU0tJS7OzsWL9+PXfu3BES8qVLlxgcHBRK+amp\nKRwcHKioqMDExITTp0+TnJwMwA8//EBERATPPPMMJ0+eJDg4mFu3buHh4YG5ubnQGvb29rJixQrG\nx8dZvXo17777LgYGBvzyyy+0tLTQ2NhIUVERzc2/Vfj29vZER0djbGxMfn4+/v7+6Onp0dPTg42N\nDSkpKcJDKzExke7ubnbu3EleXh7W1tZkZGTQ09ODo6Mj+fn5HD58+A/H75+mU9BqtYlardZLq9V6\naLXaA/9f16rVakJDQ7lx4wZtbW2Ymppy6tQppFIp+fn5VFVVMTExwbp164iPjycxMZHnnnsOMzMz\n7O3t+eKLL1i7di07duwgJiaGO3fuALB06VJMTU0RiUSUlJTQ3NyMh4cH58+fF0rcwcFBgoKCyM/P\np66ujl9//RVra2umpqYEMqysrAw3Nzfy8/OB37L4wYMHfztAHR2OHz9OTk4O9+/f5/79+zz55JPY\n2dlhZGTEjh07UKvVvP322+jo6GBjY0NpaSl5eXlcvnyZpKQkEhMTATA1NaW5uZklS5ZgZmZGX18f\nMpmMtLQ0kpKSEIvFLFiwAG9vb0JDQzl48CARERFMmzaNixcvkpKSwvz58xkeHqaoqAgnJyf8/PyQ\nyWTs2LGDjo4OnJ2dSU1NRaVScf/+fczMzIiMjKSjo4Py8nIaGhq4e/cuY2NjNDc3Y2FhgVarpbu7\nm9bWVnbu3ImFhQXXr1+nqakJGxsb0tLSiIiIwNHREUNDQ86fP89rr73G6tWrsbW1RSQSERMTg5GR\nEQkJCbS3tyMSibh//z6+vr588sknmJqaAl
 BbW0t9fT3u7u5MmzYNDw8P9PX1yc7OZunSpTQ2NrJx\n40ZSU1Npbm6mqamJ3Nxcent7EYvF3Llzh4qKClQqFePj49y6dQuAqqoqgXR88skn8fPzIz09nZ6e\nHr777jsWLlxIYmIi+vr6fPvtt6xcuZLe3l6Ki4tJSEjg3Llz+Pv7M3/+fKHnh99a0JUrV2JsbMz4\n+Dj+/v5s376d3t5eent7UavVVFRUEBwcTGdnJzk5OQD885//RC6XY2JiwtKlS1EoFPj4+PDxxx8D\nUF1dTVtbG11dXdjb23Pr1i36+/vZtGkTLS0trFixgurqam7duoWuri5WVlYMDw8THByMXC7H0NCQ\n6upqpqamsLKyoqOj4w/Hru7+/fv/8MV/Fg4dOrT/yy+/pKenB19fX4GhLS0txc/Pj6GhIVxdXenr\n6yMzM5PnnnuOqakpTp8+LUwiFi5cyNmzZ8nLy2PPnj188803lJaWYm9vT11dHZOTk7i4uGBmZkZK\nSgpBQUG4u7sLjPzdu3cJDw9n3rx53Lx5k7lz52JpaUlRURGBgYHIZDLq6+tJTEwkLi6OFStWcPr0\naaytrenq6sLPz49Lly4RFxdHc3MznZ2diMViMjMzBUZ5wYIFlJSU0NnZiUwmw9/fn8LCQnx9fcnJ\nyWHz5s2Ehoby8OFDqqurhcA2NTXF19eXpqYmZs+eTWtrK9999x1xcXH4+PggFovJysoiPj6enJwc\nPDw8mDFjBmq1GldXV8LCwtDV1RXIp6mpKYaHh1Gr1ejp6aFQKFi4cCGTk5P09fUhFovZtWuXwGc4\nOTnh5eWFkZGRcH5r1qyhtraWyspKfH198ff356effkKj0WBhYYFcLmfhwoVkZmYK7PfZs2dZtmwZ\nLi4uzJo1iwcPHqDVavnhhx8oKSmhq6uLt956i6VLl5KXlyf0179XDkNDQyQkJKCrq4ufnx9qtRoP\nDw86OzuprKxkxowZO
 Dk54eDgQEBAAPPmzSMrK4vs7GzWrl3LE088gUQi4e9//ztKpZJZs2Zx7do1\nZsyYgb6+Pjt27KC6upqUlBSuXr3K+vXreeWVV5iYmMDNzQ1HR0fkcjlbt25l2bJlnDlzhpdeeonc\n3FzefvttPvnkE+7du0dlZSWWlpbExMQQERGBq6srg4ODFBYWotVqiY6OJjc3l7y8PJRKJdXV1Xh5\neWFhYUFMTAxHjx7lvffeY3h4GFdXVzQaDdHR0XR1dXH69Gnc3d2prq7GyMgIqVRKc3MzgYGB2Nra\ncuPGDUZHRzExMaGlpQWVSoVMJqO9vZ38/PyO/fv3f/N/i8f/iKTw2Wef7ReJRGzevBmFQkFYWJjA\nph89epQLFy6QlJREQ0MDW7ZsEZ7Yurq6zJkzh6CgIAoLC4mJicHGxobCwkJSU1N5++23kclkPP74\n40L1UFpaSlBQEBKJhK6uLqysrAgLC6OmpoakpCSmTZvG0qVLaWlp4ddffyU6OpqcnBy8vLz4+eef\nKS8v5/nnnycjI4OEhATMzc2ZNWsWFy5cYPbs2aSmpqKvry8QgRYWFmzbto3i4mKMjIxYunQpJiYm\nFBUV0d3dzcGDB8nNzSU3Nxe5XM4nn3zCp59+Snp6On5+fgwMDNDT04NarcbR0ZEDBw6waNEiwsPD\nefjwIffu3UOpVDI8PIypqSkhISHcvXsXlUqFpaUlX3/9NYaGhpSWlhIVFYWlpSVyuZzGxkZiYmKI\njo5mfHycK1euIJFIMDQ0RC6XU1VVhaWlJTKZjMTERAYGBvDw8BBaCDMzM+A3UldfX5+hoSECAgII\nCQnB1dWVnJwcGhsbcXFxwdjYmICAAKHiCA8PJzk5GVdXV4KCgoiOjiYwMJBr167x2GOPcffuXerq\n6oSnm5ubGzU1NbS3t9Pe3o5EIiE0NJTk5GQ8PT0ZHh7G0NCQ8vJyvL29cXd3p7e3l7y8PMzMzEhM\n
 TGRkZIS9e/fy1VdfsXHjRurr65k5cybu7u4MDAywfv16geScMWMGiYmJTE5OsmTJEiIjI8nPz0eh\nUDAyMoKPjw+mpqb89NNPPP/881RUVLBr1y5aWlqIj4/n73//O25ubkxNTeHn50dFRQWDg4P09PQQ\nFRUlcE9/+ctfuHHjBvPmzaO2tpabN2/i4+PDqVOnWL16NfHx8bz22mt0dnYSEhJCdXU1AQEBuLq6\nUlJSQmhoKKOjo6SkpFBfX4+/vz9arRYLCwvCwsIwMTFh+vTp9PT0UFZWRkNDw/+epPDee+/t9/Hx\nQSKRkJ+fz6VLl3BycsLNzY3IyEh+/PFHFi9ezK1bt4iMjCQzM5Ply5cTGRlJUlISjY2NbNu2jezs\nbK5du0Zvby9lZWX4+/ujVCqFntDIyIi5c+fi6OhIY2Mjo6OjtLe3U1xcjJ+fH9HR0VRXV2Ntbc39\n+/dZvnw5VVVVzJkzh76+PnR1dblz5w4xMTHU1tYyMTFBcnIy3d3dlJSUoKOjw2effcb777/PkSNH\nuHfvHnl5eVy8eBFzc3NiY2NZv349bm5umJubIxaLSU5OZs6cOVy6dIkPP/wQiUSCTCZDq9WiVqsx\nNTVlYmKC3bt3k5+fT1hYGO3t7WRmZtLb24tWq2XhwoX09/cLo7uhoSHa2tro6+tDqVQyODjI2NgY\nhYWFBAQEALBixQpu3LjB+Pg4gYGBuLq6Mjo6KhCgbW1tfP3115iZmSGXy4Xpw/DwMNXV1QL5plQq\nUSgU3Lp1Cx8fH1QqFfb29uTl5eHk5ERhYSGxsbFcv36drVu3YmpqSm9vLwqFAnd3d4aGhoR5+sWL\nF4mMjMTOzo6oqCisra3R0dHBzMyM7u5ubG1tGRoaIiIigsTERORyOZmZmQwPD+Ps7MyqVauwtbUl\nOTmZvLw83N3diYyM5OjRo3z++eeMjIywYsUK1Go1SqWS8vJypFIp06dPR1dXl
 9TUVCoqKjh8+DC7\nd+/Gzs6OtLQ0BgYGcHNzIzg4mPLycoyNjQXOxtnZGQMDA4qLizE0NEShUBAYGIiLiwtr164lPT2d\niYkJ9PT0MDExITU1Fa1Wy8aNG/nll1+Ijo6mubkZtVqNk5MTXV1dQqV64MABurq68PHxoaKigpCQ\nELRaLf39/ZiZmSESiZBIJBgbG7Np0yb+9a9/YW5uLkyITp48SWpqKnZ2dvj7+3Pnzp0/lBT+IwxR\nVlZWLF68GLFYzOTkJN7e3gwMDKCnp8fy5ctpb29nfHycRYsW8eDBA3bt2sW7777LwMAAmzZtYmho\niD179tDR0SGIfwBcXFwwMjKipqaGU6dOCU+9Q4cOUV5eTkpKCvr6+ixdupTLly/j4eGBWq3miy++\nEAQi7u7ujI6O0tDQwHPPPQf8Ni6ytrZGrVbz1ltv8e2337JhwwZ27dollLivvvoqra2t+Pn5ERER\nwfbt2/H29mb+/PmYmJgQHh6OWCzG19eX2tpaAIqKiliyZAkZGRlYWlqi0Wjw9vZm4cKFvPvuu/j4\n+HDs2DHmzp3L+vXr2bx5M3V1dbS2thIaGkpISAiTk5Po6OgQFhYmVDLBwcHY29ujo6ODkZERv/zy\nC5s2bRJ4k5iYGAoKCpicnESlUnHnzh1CQ0PZunUrnp6eWFpasn79egwNDVGpVJSVlQntRlVVFUFB\nQXz44YfY2dlx8+ZNMjIy+Mtf/sL4+DiOjo4UFxdjZmbG4OAgV69eZe7cuaxcuZLPP/9cIGavXLkC\nQHBwMJcvX2ZkZAS5XE5+fj5xcXGIxWIiIyOZmppCq9Wye/du5syZw8svv0xPTw+VlZVcuXIFhULB\n8PAwK1euxNramhMnTgDw1VdfUVFRwXfffcfhw4dxcHCgq6uLiooKQTj1u0jJwcGB2bNn8/DhQ3R0\ndAgJCSEyMpIrV64wODjI008/zb59+wCwsLBAX1+fN954
 g9jYWGpra7l//z5VVVUcPnwYqVSKs7Mz\n+fn5uLm5IZVK8fT05PLlywwNDXH79m0yMzOZnJxELBYTFRUFwMWLF3n//fd59dVXCQsLw9vbm4sX\nL2JlZYWenh5eXl6cOnWK3NxcWlpaqKurE1rL3xPqiy++yJYtWxgYGCA2NvYPx+N/RKXw6aef7jc2\nNubBgwdERUXR0dHBzJkzyczMpLOzk6CgIO7evYuBgQHu7u5kZGQQFRVFeno6Z8+excbGBjs7O4yN\njfHx8cHNzY3r16/z/PPP4+npiVwux93dHV9fX/z8/EhNTcXe3p5ly5axdu1adu3axfr16zEyMsLL\ny4u5c+eir69PWVkZWVlZVFRU8Prrr/PDDz+QkpLCjBkzmD9/PidPniQ3N5d169bR3d2NtbU1urq6\nDAwMsHXrViorK4mIiECpVNLU1ER3dzd9fX3cuXOHuLg4urq6GBoaYsuWLXz++efExcXR2NiIvr4+\nMpmMuXPnkpiYyIMHD0hISGB0dJQNGzYIpOPt27fx9/dnbGwMpVKJtbU1xcXFwg+1r6+PrKwslEol\nISEhmJubMzk5SXNzs9BK/P3vf+fpp58mJiYGHR0dpk2bRl9fHxEREVy5coW2tjbmzJlDSUkJ3d3d\nJCcnExwcjJ6eHvPnzyclJQULCwshOdnb26NWq6mqqsLY2JhXX32V3NxcjIyMEIlELFu2jDt37ggk\npZ+fH99++y1BQUGkpKTg4ODAnDlzcHd35/jx4yxevJgHDx6Ql5fH5OQk8fHx/Pvf/xY0LP/6179Y\nvnw5EomE1NRUdHV1yc/Px9vbG5lMhlQq5fr166SlpfH1118THR3NTz/9xJo1a4iOjsbX15fOzk6S\nk5MFgdyGDRv46quv8PT0pLa2VtBfWFtbk5WVxejoKOHh4Vy7dg1HR0eWL19Oc3Mz9fX19Pb20t3d\nzezZs5mcnCQ7O5vc3FwaGhqQSCS
 8+OKLnDhxAlNTU0xNTXFycmL9+vUMDQ0RHh7OTz/9RHZ2Nm++\n+SYajYaLFy8KKluRSIStrS1FRUUYGhqyYcMGOjo6mD59Oh4eHtTW1gqircbGRpRKJebm5hgZGZGc\nnExlZeX/nvbhyJEj+yMjI1EqlQLjn5eXh6GhIfX19UIPrFKpyM7OJjAwEGdnZ6ZPn45cLiciIoLO\nzk5BaVdUVER2djZr1qwhJyeHvr4+9PX1efjwIUqlkuDgYKKjo+no6KCoqIht27ZhZmbGpUuXyMnJ\nYXx8nIqKCtra2ggMDEQkEmFgYEB1dTV3797lueeeo6amBvityhkfH8fY2FgQLT322GOCau33KmNk\nZARPT0/ruC6tAAAgAElEQVQ6OzsxNjbm3r172NnZUVNTQ0FBAffu3WP58uW0tLQIhF5aWhpLliwh\nICCAW7duCS3K72PY4eFh7t+/j7OzM1qtFrlcTlNTE+Pj42RmZlJQUICNjQ3h4eFcv34dOzs77t69\nS1BQENevX+e5555DJpNhbGxMXV0dV65cwdDQEIlEQlNTE2NjYwQGBlJeXo5cLic3N5f4+HhB/GRq\nakpLSwsLFizg0qVL9Pb24u7uztKlSxkcHKSqqorBwUFhbp6RkYGTkxPW1tYcP36cpqYmRkZGMDU1\nRaVScffuXdauXcupU6dISkrCy8sLsVhMWFgYRUVFhISEYGpqysDAACqViomJCVxcXJg2bRpKpVKQ\nm6tUKjQaDZaWliQnJ1NeXs6rr76Kvb09EokEExMTNBoNx44dY3x8nJaWFmxtbenv78fBwQGRSER4\neDhz584VgtzT05OGhgY8PT3ZvHkz9+/f5+eff+Zvf/sbZ86cob29nWXLllFdXY2FhQVisRg3NzdB\ndwGwZ88e3n33XXbv3o1Wq8XIyIjW1lZMTEzIyckhMDCQiYkJrl+/jq2trSA1NzQ0pK2tDS8vL0ZH\nR7GxscHFxY
 WcnBwWLVrEDz/8gKGhIRMTE6xYsYKwsDB6enqYnJzEz88P+G1KlpeX978nKbz//vv7\nExIS8PT0BCA6OlpQvxkbG5OVlUVVVRVbtmzB2tqa1tZWZs6cSUtLCwYGBnzwwQfIZDK2bNnC8PCw\nICWdNm0aTzzxBB4eHrS3txMUFERZWRmpqanMnDmTc+fOCT322bNncXR0ZGRkRJhvj4+PI5PJiIiI\nID8/n6mpKUGA09jYiFqtJiEhATc3NwYGBli8eDG//PILExMTzJw5k4GBAb766ivWrFlDe3s7Xl5e\nWFtbs2DBAszNzWltbUWlUjE1NUVeXh6hoaGEhYWRl5fHY489RmdnJ6Ojoxw/fpz169cL6sUNGzZw\n5swZ+vr68Pf3R6PR0NzcTF5enuDp2L9/Py0tLbS0tNDb24urqyudnZ3o6OgwMjKCRqPB09MTrVZL\nSkoKTk5OzJ49Gx0dHdzc3Kivrxe8Ca2trTg4OKCjo4NYLGZqaoq+vj7CwsKE4JPJZILPpLy8HGtr\na8rLy2lrayM9PR1TU1Ps7e2ZMWMGR44cwcTEhMWLF9Pf34+fnx8rV67kyy+/5JVXXqG7u5unnnoK\nY2NjKioqaG1txdPTk7t379LY2Eh/fz/z5s2jvb2dHTt2cOnSJRobG9m0aRP9/f1s3LiRzs5OysvL\nWbNmDefPn2fGjBnk5eURGxuLnZ0durq6mJqa4uzsjFQqxdLSUhAX5efnk5OTQ1hYGMnJyUxMTGBr\na4u9vT2jo6MkJiaSmZlJRUUF/v7+uLm5ERISwuXLl/H29ubBgwfExsaiVCoJDAwkLS2N0tJSVCoV\nZmZmNDU1YWxsjIuLCwDW1tbk5+dTW1tLS0sL+fn5qNVqpk+fzuTkJJs2baK3txcrKyu6uro4duwY\nnZ2drFy5kh9//JHp06cjEolITU0lJiaGzz//nL179/Lee+9ha2uLRqPh4cOHVFVV/e/hFCw
 sLLh2\n7RpZWVmkp6eTlpbG4sWLsbe3Z+PGjdjY2BAbG8vp06dJSkrC3NycK1euYGpqypdffsn+/fsJDw9n\nYmKCsbExQVgyMTHB6OgoN27cwMvLC5lMhpeXF7t27QJg9uzZWFlZUVNTI6jmRCIR77//Pjk5OVy4\ncEGoHqZPny6YeqZNm8b8+fOJi4vjxx9/pLW1lTt37tDf3098fDwRERH89a9/FbK7QqFALpfj4OBA\nYmIin332GWlpachkMjZs2CD0e0qlkuXLl+Ps7ExOTg5RUVGYmJgIZJa+vj4jIyPC6DAjI4PAwEAa\nGhpwcXFhx44dKJVKlEolJ06c4IknnmBsbIyysjLB8FNRUUFSUhIzZ87k7bffprCwED8/P5YuXUpP\nTw+lpaV4e3tjYGAA/GaqEYlENDY2IhKJKCgoQCaT4efnR2FhIf39/Wg0Grq6uvDy8qK8vJwHDx4w\nODjIrl278PLywtPTk+zsbNzd3QWBzrPPPkt6ejoODg4CMw/wr3/9i8DAQKampqisrCQyMpLu7m7e\neustAgMDiYqKIiQkhKqqKnp7e3nxxReFFrGpqYnm5maCgoKYNWsWvr6+6On9Zu95/PHHWbhwIZcv\nX+bs2bMsWrSI3Nxc6uvrsba2Ri6X4+rqikKhQK1WExQUxL179/Dz88PW1haFQkF3dzcnTpygsrKS\n5cuXC79fT09PwUQWGhrKnDlzuHPnDlKplMrKSmQyGUFBQcTExGBra4uFhQVXr14V5OgpKSl4eXkR\nEBDAO++8A8Bf//pXrK2t8fDwYOvWrdjY2NDT00NISAhHjx5lbGyM4uJiPDw8hEpxz549jI2NERwc\nzMWLFzl48CABAQHo6+sLCsw/gv+ISuHw4cP7t27dKijSDAwMKCoqwtnZmRMnTgjz5qVLl/Lyyy+j\nVqu5evUqIpEIb29v/P39qa+vZ9asWRQUFAgjv5MnT3LmzBkWLFhAeX
 k5LS0tdHV10dzcTGJiIgqF\nghkzZtDb20tsbCxubm6YmZlhZWVFQEAATz/9NIGBgcyaNYukpCRmzJjB1atXeemll+ju7mbx4sVM\nTk4yNTVFWFgYhoaG1NbWcvbsWQYHBwkMDGTJkiWo1Wru3bvH+Pg4lpaWBAYGUl9fL4hSJBKJwKbP\nnz8fhUJBa2srAQEBZGZmoqOjQ2BgIGKxGDs7O4aGhvj888+5fv06Q0NDzJ49m59++om+vj7Cw8OR\nSqXMnTtXUBqOj49TUlLCxo0biY+PF9yYarWayMhIQbDz4osvolQq6e7uRk9PD319fcRiMUFBQYJD\n0MLCgv7+fpYsWUJHRweOjo6Ehoby/vvv8/PPP7Nr1y48PDzYuXMnr732Gt7e3hw5coT4+HgqKytx\ndnamoaEBHx8fQYRz8uRJLl68SFtbG9988w3u7u5CcqusrGTWrFmsWbOGsrIyRkdHiY+P58qVKyxZ\nskRwUDY1NWFiYsKqVavIzs4mIyOD8PBwysrKuH37NqGhoTg6OlJZWUlISAgpKSmsX7+eiIgIRCIR\ne/fuZceOHfzzn/9k//79FBYWMjo6ioODAwqFAg8PD6ZPn05/f7/QBvx+z+bmZsbGxgRy9Nq1a+zd\nuxepVEpHR4eQXK5fv86yZctwdHREo9FQX1/PgwcPqK+vFyTWn332Gffu3ePKlSuCA/Z338bvoqye\nnh6cnJzw9vamqqoKHR0dYez8O3/l5uZGRESEYC5rbW2lqKjof0+lMDg4iLW1Nb/zCoODg0xNTTF9\n+nRmzpzJ6Ogoq1atorCwkB9++IG8vDw++OADRCIRU1NTFBUVCUHu4eGBXC4H4PXXX2fBggX8+9//\nxsDAAKVSKdho/fz8kMvlZGRk0NLSQnFxMTdu3KCiogKRSERSUhIHDhygqKiIsbExbG1t6erqAqCh\noQG5XM4LL7xAf3+/8DQeGRlBpVLh4ODA/v37c
 XBw4OrVq5SUlODv749arcbGxoaIiAh8fX1xdXXF\nwcGBX375BYBnnnmG1tZWzM3NkcvlpKSkoNFoaG1t5dKlSzQ3N6Orq8u9e/cIDQ0lJycHXV1diouL\naWpqoqGhQbBDHzt2DH9/f/Ly8vDy8iItLY0rV64IbsLq6mpMTExoaGigt7eXlStX8u9//5uYmBgq\nKioIDQ1lcHAQlUollLv5+fkMDAwwMjKCgYEB06ZN48aNG7S3t3P+/HmWLl2Kq6srpqamXLp0ibt3\n7zI5OUlycjKTk5OCJ0QikXDo0CHmzJnDp59+Sn19PTt27ACgvLyczZs3o9FoGBgYYM2aNXz88cdM\nTEywdOlSZDIZeXl5rFmzBhMTEzw8PFi7di179uzhtddeo6SkBJVKha2tLZmZmfy+RMjY2FiwNbe0\ntPDjjz9SU1PDpk2buHfvHjt37iQrK4utW7dy4MABLCwsGB4epr29nRUrVnDmzBkOHTpER0cHp06d\nEioQPT09XnnlFRQKBTt37hTs22+++Sb9/f3U19ezfPly3N3duXr1qjBVs7GxYc6cOQQEBLB9+3aq\nqqq4ffs2Tz31FABbtmxBJpPR2dlJW1sbUVFRxMXFMTg4iKmpKf7+/nR2dlJTUyNI1eVyOXZ2dhQU\nFNDU1CTI6lUqldAm/xH8RyQFKysrYfy0du1aFi9ejIWFBc7Ozujp6eHm5kZzczPu7u5oNBokEglH\njx7l5s2bLFy4kKeffprw8HCKi4u5c+cOvb29ADg4OJCRkcHmzZsxNzdHoVAQGhoqyJIfPnzIwoUL\nUalUZGVlMTAwgFgsxtzcnCeeeII9e/YglUrJysoiJSWFTZs2AQjjo3Xr1uHt7U1MTAwTExMUFBQQ\nGBjIY489xrp161CpVOzduxc/Pz+ioqKE0efp06dpbW3l3Llz9PX18de//hX47QdWVlaGo6Mj5eXl\nwvzez8+P5cuX09bWRlNT
 ExEREdjZ2VFWVoaxsTHDw8P84x//YPny5ejq6mJjY8Pq1aspLi7G398f\nhULBsmXLcHBwwNLSko8++ggDAwPa2tqIiIhgeHiYoaEhQROhVqu5c+cOzs7OdHd3k5qaire3t/Dk\ncnR0JDMzk6GhIV599VXGxsaQyWR4eHjQ09NDdXU1169fZ+HChYIzUU9Pj4ULFzJv3jycnJwIDAzk\niy++4PHHH2f27NnCWNbQ0JDt27dTV1eHmZkZEolESKDp6ekMDAzw/PPPk5qaSkNDA2vWrEFPT4+U\nlBRWrlyJVCqlvr4eqVTK9u3b8fDwAKC+vp6qqio8PT1ZtWoVn376KaWlpaxevRo9PT0iIyNxd3dH\nIpFw5coVnJycAGhpaeHTTz/l2WefJTw8nG3btiGTyTh37hwA4eHhgluzv7+fyclJDhw4QHx8PHl5\neTg6OtLR0YFIJOLIkSN8//33XLhwgfz8fAwNDQVNzRtvvEFLSwsFBQUAwvkaGRkxODgoqHzt7e2p\nqKgQiFVfX19SUlKYOXMmBQUFtLe3s337diYnJ2lvb6ejo4PKykoUCsUfjsf/iKTQ1NTEwMAA/f39\nTE1NkZaWRllZGd999x1yuRxfX19cXFwEA4tarUYmk7Fq1SoSExOJj4+nqalJMCWJxWIANm7ciKWl\npSAqMTc3p6Ojg3/+858EBwdjYWGBq6srhoaG7Nu3j23btuHi4kJ5eTnnz59nYGCA3t5e7t+/z5tv\nvik4zUxNTUlJScHZ2ZkLFy5gYGDA5s2bKS8vZ9myZQDcuXNHMGRt3bqV8+fPk5GRIUiif5+xh4aG\nkpqaCsDAwADZ2dmCE/L3sWVCQgKDg4PExcXh5eVFRkYGQUFB+Pj4cOLECWpra8nMzMTa2pq6ujrS\n0tJQqVScPXtW2I8gk8mwsLDg6NGjiEQiFixYgKmpKR9//DHe3t74+PjQ0dHB7du32bBhAzExMYyO\njhI
 REYFEIsHBwQEbGxumpqYoKCigq6uLf/zjHxw7doyUlBQ6OjoICwtjdHSU0tJSNmzYIPT4hw8f\nprm5mZSUFOrq6ggJCcHT05OAgABqamoIDw8X5vPFxcUYGBgwMjKCm5sbR48eZdq0aejo6BAUFER/\nfz/Xr19n7dq1aDQacnJySEpKwtnZmTlz5uDr64uhoSFTU1PMmDFDMLGNjY3h6OhISUkJ7733Hnl5\necyZM4eIiAjMzc05cOAAycnJiEQiTp8+TXl5Ob29vWzatIm4uDhKS0tJSUlBqVQyOTmJVCoFfvPB\nlJWVYWlpyaVLl6isrOT48eMolUoqKipwcXHB3NwcY2NjbGxsOHPmDJGRkSxZskTYX2Fubo5arWbJ\nkiV0d3cDsG3bNsRiMV5eXoJuZ8GCBYSEhPDYY4/x8OFDBgcHcXR0ZPfu3SiVSlxcXCgrK8PIyAgL\nCwuBH4mIiMDY2PgPx+N/RFJwdXXl0KFDGBsbc/36dVauXMlLL72Ev78/Q0NDpKWlYW1tzfz58zEw\nMKC1tZUVK1YwNTXF5OQk0dHRSCQSwZBTUfHbKsjvv/+e5uZmlEolPT09FBcXo9FoSEpKEnYvNDc3\n093dzZEjR6iqqhK2Nm3fvl3wL4yNjdHT08P06dMB6Onp4f333+fmzZuEhITw/fff89VXX+Hk5MTu\n3btZt24dycnJ6OvrU1JSwttvv82qVavo6+vjpZdewsLCgmeffZbu7m66u7tZtGgR8FtS+J1x1mq1\njI6O8sorr1BQUEB5eTklJSU4OjqyY8cOpqamCA4OxtnZmZkzZzI2NkZfXx8lJSW4uLggk8mIj49n\ny5Yt9PX1oVAosLS0pLCwkPDwcFauXMmuXbuIjY3FzMyM1tZWgoKCyMvLo7W1leTkZM6dO0dBQQGR\nkZFcuHCBnJwcRkdH8fHxISkpibVr1xISEiJslUpMTBRY+5s3b1JbW8uuXbuQSCQE
 BwejVCqJjY3l\n7NmztLa24uTkxIYNG7C0tCQzMxP4TTbt5OSERCJBoVDwO9fU09Mj7Daoq6ujsLCQ1tZW+vv7uXjx\nIl5eXvj4+HDr1i06Ozvp7+8nPDwca+vfFg0FBQVx8uRJpqam8PLyQq1Ws2rVKgYGBqirq2PdunV8\n9913GBkZ0dfXx8yZMzEyMuKdd97BwMCAn3/+mY0bN5KcnCzoZwBiY2MpLCzE3d0dLy8v+vr6iIqK\nQqvVsnfvXhITE9HT08PW1pYHDx6wZ88eSktLSUxMpLKykurqakJCQmhvb+f48eMkJCQA4OzsjLW1\ntSDbnpiYwMnJSXDVarVaFAoFbW1tjI+PI5fLBXNbU1MTtra2+Pr6olKpaGtrIyUl5Q/H439EUujr\n66O3t5eBgQFB8FJaWiro0DUaDbdv32Z8fBxXV1ecnZ2pq6vjxo0bODo6MjExwaJFiygvL8fDw0Po\n0RMSEnjnnXcYHR0lKytL2IMQFhaGhYUFwcHBlJWVIZFI2L59O0NDQ1RWVrJmzRrS0tLIyMhALBaj\nr6+Pvb099fX1APT29vL4448zNTWFsbExS5YsEbYglZaWcuvWLeGpaW1tjYuLixA4165dE5ZqfPDB\nB4yNjZGXlwcgrOkyMzNDR0eH9957j7NnzzIxMSG4+FJSUhgdHSUgIEB4L/hNZanValm0aBG6urrU\n1tYyOjpKTEwM+/btE7iLsLAwmpqaePXVV6murubhw4cMDw9TX19PXV0dCxcuZO7cubi6urJz505c\nXFy4du2aQOLJ5XIsLS158cUXqaurw9DQEH9/f+7du0dERAR79uyhqamJp556ivb2dkE8deTIEVpa\nWhgcHESr1dLW1kZnZydff/013d3dQoUVFxfH0NCQMA4+dOgQoaGhtLS0oFQquXr1KmNjY4yOjjI1\nNYVUKhW8MjY2NoICceHChRw+fJimpibgt7HfBx98wKpVq1i
 8eDEzZ86kpqaGV155hXPnzmFtbU10\ndDTm5uZ4enpSVFTE008/ze7duxkbG8PGxobMzEy8vLz46KOPaGhoAEAqlfLyyy9z48YNXFxcMDAw\nEDQHIpGIF154gTt37mBvb09ycjIrVqygubkZuVyOl5cXcrmcM2fOsGrVKuLi4gT9i1qtRldXl3fe\neYcDBw7Q3NxMTk4OMTExQuX7+7i0pqaG77//XjBJGRkZceHCBYaGhnjqqafIzMwUKps/gv+IpGBk\nZISHhwcTExNUV1cjl8vJysrCwcGBr7/+Gh0dHUxNTbGysuLmzZv4+/sjEomYOXMmhYWFzJ49W9jR\nqKenR1FREQDnzp2jtraWX3/9lVWrVnHlyhV8fX1RKBSsXr2a/v5+LC0tWbVqFenp6RQUFLBmzRpa\nWlq4d+8e7u7ueHp6EhMTw7lz53BwcAB+Kxk/+OADcnNzKSkpQVdXl1WrVmFiYkJoaCg//vgjDg4O\nhIeHM2vWLHbu3EltbS3Tp09nw4YNNDY2Eh8fL4hb3N3dAbCzs2PRokVotVq0Wi1bt25Fo9EQGxtL\nb28vUVFRqFQq8vPz6e/vx9/fn9DQUIaGhti5cydRUVFcv36dgoIC8vPzGR4epq2tjeeff57+/n58\nfHwEZ6ZGoyE9PZ3IyEi0Wi22trbCyDYrK0sQjqlUKmJjY2lqamJwcBA7OzsqKiqwtLRk8+bNDA4O\nkp2dzcjICDdu3BC4id/XoNnZ2dHa2srSpUuRSqVUVVWhq6tLS0sLTzzxBFKpFG9vbz799FMAvv32\nW2FUOTIywqpVqygoKCApKYmYmBhhf6eLiwtyuZyKigqcnJyoqqpCo9Hg5+eHRqNBrVZz5MgRoWy+\nefMmv/76K9988w3FxcW88cYb/w977xlW5bmu7Z6D3gZIUYqgUgPSESmKNEFFRVRUjC1Ro84YNcWS\nzKwkTk3iNDGWRGMSNMaKxEKwgQJipU
 gXEUE6SO8C0hn7h3M8e63j+I5vZe211/HNtfd6/lAEZDDG\n+7z3c9/XdV4cOXKEd955hzfeeIOEhAQ2bdoEQH5+PrW1tfT19dHX14eZmRmrV68WZKv+/n5x8dbX\n19Pf309qaioaGhrk5eWho6NDVlYW586d4+zZs/T396OhocGuXbvo7e1l8+bN1NXVMTIywgcffICS\nkhJ79+7l5MmTorIpLy+ns7OTefPmsWLFCuzs7IiPj+fp06cCc7dv3z7eeOMNEhMT8fLyEtqLtrY2\nALS1tcnJycHd3V0cqf/M+i9BvP9Hl0Qi+T//S/zP+p/1//2VLZPJ3P+9L/o/Bm7918vExIT4+Hji\n4+MZGRmho6MDAwMDiouLmTVrFoWFheTn5/PkyRN++OEH1NXV+eWXXzA1NWXWrFk8e/YMGxsbhoeH\nuXTpEjKZjF9//ZWbN2+ybds20SkuKioiJyeHuro6FBUV8fDwwMDAADs7Ow4fPoyDgwN6eno4OzvT\n29vL06dPUVRUREVFBVtbW3bt2sWlS5fIzc3lo48+4uXLl8JG7eXlhb6+Pn19fVhZWQkTU319Pa6u\nrmRkZKCkpMTw8DDh4eHcunVL3J1v3brFuXPnuHjxImpqalRXV5OdnS38/erq6ly9ehUnJyfs7e05\ne/YsgYGBSCQSqqqquH37Nh988AElJSWEhYVx7Ngx4QF49913CQsL49atW0Ji7erqyowZMzh37hz3\n798nNzeXiRMnMnPmTPLy8qiqquL999/HwMCAjIwM0SdYuXIliYmJNDU1cefOHUxNTQkKCiI3NxdL\nS0sxlr1z5w5aWloEBQXR3d0tDFclJSXIZDJMTU2ZPHkyly5dwtzcnJKSEiZPnkx4eDjr16/H2tqa\n/Px87t69S0BAALq6unzxxResWrWKV69ekZ6eLjwVJiYmrFy5UhCsX716JdShv//+OxKJhKioKFas\nWMGKFSsoLi7m2
 rVr7Ny5k4sXL+Lr68utW7eIjo5m9+7duLm5kZycjEwmQyqVMnv2bBISEujv76e2\ntpbAwEBUVVWxs7MTlu78/HxiYmIwMjIiPDwciUQiOBQ7d+7Ezc2N9PR0li9fTltbGzdu3BB6BAsL\nC0pKSsTEx9XVlS1bthAbG8vLly/Zu3cve/fupbKyEj09PdTV1Xny5AkTJ04kJiaGkJAQsrOzefTo\nEWvXrsXe3p59+/axZ88e4uPjRQOysrKSXbt2/anr8Z9CvPTxxx//7cmTJ0JmOzw8TGNjI0uWLGH8\n+PEoKCgwevRoPvroI1JTU5k0aRLDw8N4e3vzzTffMH78eJqamrCzs2PlypUMDg5y+fJltm/fjqmp\nKSUlJQwMDFBUVISNjQ1BQUFCWDI0NMSTJ08oKChgxowZTJgwgYSEBMFlGBoaEufxyZMnc+3aNaEF\nWLNmDTU1NYwbN04Qjjo6OigoKGD69OmMjIygr69Pe3s7pqamYmoya9Ysbt68KYAqU6ZM4cKFC3h7\nexMTE8OkSZPYvn070dHRDA0N0dDQIMZQcu7D/PnzOXr0KAMDA0ybNo2goCBsbGyor6/H0NAQX19f\nOjs7Wbp0KV988QXBwcGCLiwv3VNSUpg6dSrl5eXMnz+fhw8fMm7cOIyMjASiraqqSszCAwIC0NTU\nJDIykpSUFBYuXMj3338vMG8bN27kzp07zJ49WyDX3dzc+Omnn+jo6GDt2rWkpaWhra1NeXk5UqmU\n4uJioYhMSUnh3XffpbW1FT8/P9zc3Dh69Cj79+8Xx7Lk5GQCAwMZHh4mIiKCjIwMcnJygP+b9Vld\nXY2GhgavXr3CwMCAhw8fEhYWxsqVK1m8eDFbt27l+fPnvPHGG+Tk5GBubs7AwAA2Nja0tbWhra3N\nvXv3yM3Npba2lvDwcNLS0ujp6WF4eJhff/2V3t5ekpOTUVZW5uHDh2zfvh0jIyPOnj1LU1MTjo
 6O\n7Nq1i5CQEB4/fkxgYKDwxGzZsoXo6GihGYmKihIy8aCgICIjI4XgbuPGjQwNDQmfyf3795kzZw7N\nzc3o6uqyb98+li9fjq+vLwkJCXh4eBAcHCygLvKbVHp6Oo8fP/7vI14yNjZm586dAo4plUqZN28e\nfX19QtY8btw4fvjhBzQ1NcnPz0dLS4uRkRHef/99nJ2dcXJyErp8ead1zJgx1NXV0dDQgJ2dnbho\nL168iK6uLo2NjZSUlNDd3Y2vry8tLS0C2PHbb7/h7e1Nfn6+eEG0trYCsGHDBubOnUt3dzf+/v4Y\nGRlx/fp1zpw5g6WlpRDqjIyM4Ofnh5qaGo8fPxbd6WXLluHi4kJ0dDQTJkwQ51Nvb282bdrErVu3\n+Oyzz1BSUmLevHno6Ojg7OyMu7s748aN4/r161y9epV169YJutONGzf4/vvvsbS05PHjx5w/f57l\ny5cTFRXF4sWLOXz4MGlpaTx48AAvLy/KysoYO3Ysp06dEuizwcFBbt++TUFBgTjbamhoUFhYSGBg\nIO7u7uzbt4/JkycTHBxMcnIyurq6AhtWUVHBo0ePRH9HKpWSkZEhNqaoqChcXV2RyWTU1NTg5OSE\njl8fRr8AACAASURBVI4Onp6egqU4evRovLy8KCgo4Mcff+Srr76iqKiIPXv2cPDgQTw8PFi/fj3d\n3d08fPiQ6dOns2rVKvT19TEzM+PBgwe4ubmRlZVFcnIyvb29wOuewp49e1i3bp2ABCsoKLBo0SK6\nu7v56quvyMnJQSqVoqOjw/vvv8+kSZNYtmwZDx48wN/fHy8vL1xdXZk7dy7Pnj0DwMvLi8jISM6c\nOUN3dzfJycmMHj2aoqIi0R+ysLDA3Nyc3bt3Y2xsTHt7Ox4eHmzdupVXr16xf/9+XFxcyM/PF2Pv\noqIi1NXVxaYzMDDAs2fP6Ojo4Pr166K/sXLlSgoKCqivr8fIyIgjR47w9
 OlTysrKRDP23r17LF68\n+E9fj/8UlcLx48f/Jh+JOTs7Y2NjQ0pKCklJSaxcuZLo6GiWL1+Ojo4O7e3tlJeX09PTI0Jcbt++\nTXFxMRoaGtTV1WFtbU10dDTm5uYoKCjg6OjIL7/8wsqVK7l06ZLg9s+ZMwcTExO6urro7e3F29ub\n5uZmSktLRammqqrK7NmzUVdXR1dXl0uXLhEWFiYAK4aGhty+fZsNGzagr69PVlYWL1++RFFRkebm\nZvbv3y+YCvHx8ZibmyOTyVBQUMDb25uRkRHMzc05e/YsOTk5gmlobW2NgYEBT58+ZWBggKGhIfLy\n8gR2btu2bURGRuLo6CgQdtbW1pSVlbFo0SKGh4f58MMPCQsLo7q6Gh8fHwHpiI6OZtmyZXR2dvL2\n22+joaHBb7/9Rl9fH/X19dja2gqVo7KyMsHBwbS1tXH+/HlMTU1F8Iyenp6gI2VkZPDq1Ss0NDRI\nTU1l6tSp5OTksGjRIj777DMRIiP3KSgqKvLrr7/i5OTE+PHjqaqq4s6dO7zzzjtkZWWxbds27O3t\nMTAwIDc3FycnJ2pqahgYGKC0tJS4uDg+/PBDlJSUyMzMJD8/n+bmZj766CN+/vlnfHx8eP/992lt\nbSUhIYE5c+Ygk8kwMDCgpKRETAra2tooKiriwoULzJkzBwUFBU6fPg2AqakpysrK/P777zg4OKCu\nrs6VK1eor6/H3Nyc+/fv4+vrS2trK+PHj8fAwABra2seP36Mvr4+TU1NvHr1ir6+PpycnIiLi8PJ\nyYn4+Hjh2wGIioqioqICFxcX7O3tiYmJEfzR5uZmAXRxc3Nj/vz5JCQkYGNjg5aWFo6OjkRGRgqm\nSE5ODra2tuTn56OmpkZhYSELFiwgMTHxT+PY/ikqheHhYebOnYurqytnzpzh008/Zfr06QQEBBAb\nG4uOjg7R0dGoq6vz7bffEhERgba2tpAEDwwMkJ+f
 L3j/ckWjsbExUqmUzs5OjI2Nyc7OZsmSJQKv\nVVVVxfHjx5FIJIwaNYr3338fJSUlce6NjY0lKChIBJKoq6sDr1Vuz58/x9bWVkiOU1NTuXz5MoOD\ng6xfvx5HR0ekUikbN27E1dWVP/74g7lz5zJ69Gjmz5+PhYWF+L3kaj4HBwcBDPHx8RF/nzFjxtDd\n3Y2tra0w6/j5+fHNN9+Qn59PSEgI6enptLW14eXlxYEDBxgeHubdd98Vd40LFy6QkJBAUlISO3fu\nRElJSWDcy8vL0dTU5K233hLZGlKplKVLl9LS0oKioiKPHz9m5cqVGBsbExISgpeXF0uXLkVZWZmF\nCxcSFRVFc3Mzfn5+zJ8/nwcPHrBp0yaePXvGsWPHxBGspKSEDz74gMHBQbZt28a9e/c4dOiQAKHq\n6upSVFTEkSNHSEpK4vr165SVlXHr1i0mTpwokqpmz57NyZMnOX78ONbW1sTHxxMSEsKFCxewsLBg\nxowZREZGiipsz549aGtrExQURH9/P7/++iu5ubm8ePGCmTNnipyPsrIyli1bRlpaGnZ2dsIxe/bs\nWfLy8njvvfdwcXERIB8XFxeampq4cuWK2MACAwNJTU0VEzM1NTUGBwdZtWqVUD52d3fzL//yL0IT\nI0fS9ff3A69jA+rq6lBQUKC0tJT33nuP9PR0ampq0NXVFXQwqVTKV199hZubmzDLxcXFMXXqVN54\n4w08PDwoLS0Vk5U/s/5pKgV5/Janpyc1NTUEBQXR19cnqoENGzYwevRo9PX1KSsrw8zMDHt7e5SU\nlNDV1eXTTz8lNjYWZ2dnfH19OXjwoKD++Pv709bWRktLC3V1dbS1teHv709+fj6WlpYYGBggk8mw\ntbWltrYWKysr2tramD59Ojo6Oty9e5dp06bx/Plzbty4wZQpU2hoaMDHxwcNDQ2kUimjRo3C29tb\ngF0jIyPR1dXF2dmZy5cvi5m
 6fISoqKhIdnY2WlpaREdHU15ejo+PD46OjtjY2NDc3IyNjQ2Ghob8\n/vvv6OjoMHPmTPbv38+iRYuIiIjAyMiIkpISzpw5g5eXlxAK/fDDD7x8+VJEp3l5eeHv7y8aq9bW\n1pw7d47w8HC6uroEOkxHR4e0tDTMzMzw9fXlxYsX5OfnC+PYyMgIZmZmmJmZ0dzcLNSijY2N4oLL\nzs4WQT5yGffWrVvx8/NjeHgYFRUV7OzsuH79uriz+/n5kZWVxZUrVzAyMhLUZrmzT19fH2VlZWpr\na5kyZYpwjaqqqjJr1iwuXLjA3r17uXfvHp6enowZM0aATGxsbIiPj2fOnDnExsZibGyMiYkJDg4O\nDA8Pi35TVlYWhoaGIpRm4cKFJCcn4+npSX9/PzU1Nbz77rvcv39fNJ7l1ns5pau0tBR/f38AHB0d\nOXr0KOnp6UydOhVPT0/q6uoYN24cxsbGIpNC3kNLT0/H2NiY6upqEhMT0dPT47PPPqOqqoqBgQGa\nm5sF3EZOjdLT0+PRo0dMnDiRlpYWobNxdHQU4Taamppoamryyy+/UFxc/N+nUmhsbMTJyYnu7m6O\nHj1KV1cXV69excDAgMePH+Pu7o6VlRVvv/02bW1trFy5klu3bgGvwRV3797l559/RkFBgZcvX3L3\n7l0Aent7WbBgAXFxcXh5eVFZWUljYyP5+fmcP3+eV69eERQURGpqKpqamshkMsHVz8/Pp6WlhczM\nTDQ0NEQHHV7LnM3NzTEzM8PS0hJ1dXUaGxt58OABgYGBREdHc/DgQWG08vHxobe3l8uXL3PkyBFa\nWlqIjY1lwoQJlJWV4eHhAbw+T0+YMAFFRUWKiorIy8sTQNr29nbu37+Pvb09t27dQkFBgY0bN+Lo\n6MjKlSvp7e0lKyuLW7duMXPmTLS1tVFRUeGjjz7i3r17QuCya9cuLly4QGNjI2lpady+fRsdHR1u\n3bpFRU
 UFeXl5XLlyhStXruDl5UVgYCADAwMMDw+Lsj0mJoampia6urro6uoS3ffnz5+Tl5fHhQsX\nUFJSwtvbmy1btrBmzRouXryInZ0d2dnZqKioMHv2bLS1tXn27BkNDQ3/ploaO3asQKafPHkST09P\nAgICsLW15fnz5xw+fJiFCxeKxqutrS15eXmiMly3bh1Hjhyhp6cHM7PXQWXyvMuCggLef/99mpqa\nOHv2LGPHjhW+lObmZhoaGrh586agIr18+RJHR0e2b9+OoqIig4ODnDhxQugf3n77baFVcHV1pba2\nVgBTb968yZQpU5BKpYSHh/P8+XNxxHJyciIwMFDg+caPH4+ZmZnwKBgZGRETEyMet/y40traSnx8\nvLDyyytNuUZn0aJFIjxGHtrT0NDwH7JO/1NsCvJmlfwu//jxY9rb25FKpdjZ2XHz5k22b9/O5s2b\n6erqEiWjoqIiS5cupaqqiuHhYd555x3hzwdwdnZGU1MTOzs7cnNzhdddjiubO3cu9fX1rFixgrq6\nOsrLy1myZAlVVVW89957ZGZmCjhGbGyseCGYmpoyODjInTt3UFVVFYYYORK+u7ubwMBA1q9fLzBk\nFhYW/P3vf0dZWRlVVVWmTJlCcXExLS0thIW9DuSWN0LLy8s5efIk3d3d3Llzh8LCQrZu3YqBgQF+\nfn6imTpz5kxGjRqFg4MDTU1NfPXVV7S2ttLY2Mj48eNxdnZmcHCQkpISbG1tefPNN9m9ezdaWlpk\nZmZSWVkpKpeBgQGcnJwIDw8XXIknT57Q0tJCdnY2tbWvU/+srKzw8vIiNzeXxMRE0ROQj93kG5S/\nvz8mJiacOXOGMWPGsG3bNqE0VFNT4/79+2zatAllZeV/02icOXMmcXFxjBkzhq6uLqZNm8aYMWPY\nuHEjCgoKokF56dIlIiIiGBkZYdGiRaLSKisr4/Dhw/z444+sW7eOb7/9FgAtLS1SUlK
 YNGkSixcv\nZt68efz+++/MmDGDly9f8scff1BUVISdnR2HDh3i3r17lJWVoaKigqenJ1lZWVy+fJnTp0+zdOlS\n0Wj8+9//zosXLwTWXn5czczM5OTJkwQHB6OiosKWLVtwd3cnLy+Pa9euMX78eBoaGkhJSSE3N5db\nt24JtB3Apk2b8PT0JDU1VaRgmZiYYGpqirGxMYqKivT09NDR0cGNGzdE2Gxubi52dnaUlZWJ5qK+\nvv5/qNH4T7EpyGfzkyZNQiqVEhwcjJubG8eOHcPHxwepVMqBAwdEMvLmzZupqanht99+w93dnQUL\nFggllzxfD16f906dOkV6erpAi7948UKo8c6dO4eqqiqdnZ20tLQQFBREcnIy1tbWdHV1ERERgYGB\nAd3d3Zw5c0ZsCvHx8djb2+Pt7U1/fz9SqVTYkl1cXEhNTcXJyYkTJ04IKo486FZJSUkkH8sJy8XF\nxcBrvXtOTg73799n165dTJs2jdmzZxMcHMyDBw+EgcbW1hZ1dXXy8vIwNzfn/PnzALi5udHR0SFS\ns6urq9mzZw979uxBQUGBr776CnV1ddra2ggNDRUv+itXrmBsbExDQwMmJiZs3ryZefPmCeqwjY0N\nSkpK+Pr6IpFIMDAwwMTEBGVlZZKSkmhra8PU1BQLCwsuXLiAra2tsMNPmzaNSZMmoaGhwblz50Qm\nw4MHD4iNjaW/v5+oqCg8PV+HkkdGRjIyMoKzs7OwzZeWlrJ9+3YGBgYwMTFheHhYBL86Ojry66+/\nYm5uTnNzM8rKyvj6+iKTyTh48CDr1q0DICUlhVOnTonMz9u3b7Np0yba2tq4fPkynp6eDAwMIJVK\niY6OZty4cVhaWjJr1iyioqIoKytj4sSJzJkzh1GjRgmj1dq1a3FxcWFwcJC7d+8SFhaGpqYmGhoa\nPHnyBJlMhoeHh3ArGhsbM3PmTMF2cHJywtvbm08//ZSlS5dy8u
 RJ4DXc5vTp0/T29tLc3Cyajm5u\nbqioqBAfH4+BgQGjR4/m888/x8TEhJGREVavXs2dO3fYvXu3IEnn5uZy5MiRP309/lP0FL755pu/\njRkzBlNTU+rr6/H09ERdXR0tLS3Mzc2pqalBT09PlNd1dXVUVFTQ0dGBs7MzQUFBIljEy8uLadOm\nsXfvXuzs7EQ6zkcffURHRwd1dXXo6+tTXV39b7wMurq6mJubM3fuXPbt2yfOlMXFxcycOZN58+aR\nnJxMdnY2p0+fJj4+nqtXr9Ld3Y2fnx/379/H3NwcDQ0NwXMYNWoUampqYtogz4J49eoVnZ2dmJiY\niAvo9u3bbN68md9++40VK1bQ0dEhxoanT59meHiYNWvWcPToUfT19UWm4LVr15g+fbpwFTo6OqKp\nqYmbmxvOzs6Ym5ujrq5OS0sLgYGBjBo1itLSUrq7u/n8889RVVXl+fPnTJo0iTNnzrB3717h2tPU\n1OT69euCTCTvxstzJuR/OzkrMDMzk4GBASIiIoRX4caNG9y+fVtsYj/++COjR49m5syZKCoq0tnZ\nSW1treBfrlmzBm9vbxISEjhy5Iho9DY2NmJmZsbLly+xtLQUidWlpaXY2tqipaXFjRs38PDw4Kef\nfhIuQSUlJZKTk1FSUuLx48c4Ojpy+fJlIUCLjY0lLCyMkpISPDw8RLNOntMxPDzMtWvX+Pbbb1m7\ndi0bN27k/PnzGBgYkJWVhZ2dHTKZDEVFRS5dusTTp08JDw8nJyeHKVOmCN1KSkoKurq6IuDnxYsX\neHl5cfjwYQwMDGhubqa9vR2JRMKjR4+YO3cuzs7OtLS0oK+vT3NzM7Nnz+bmzZv09PSgqakpNsiM\njAzU1dXp7u7m5MmTSCQS3N3dhSXdzs4Oa2trYmNj//v0FPr6+tDS0iI5ORmpVMqmTZu4evUqurq6\nbN68mcuXL/PgwQPGjh1LXV0dP/30E/39/
 eJBJyYmUlFRQV9fH6mpqWLUM3bsWNHYiYqK4tWrV6ip\nqdHV1YVEIsHW1pZJkyZhaGgozDQHDx7E3d2da9eu0d7ezrJly6isrOSLL77Az88PeA0C6evrIzQ0\nFEdHR0aNGoVUKsXJyYno6GjGjx+PiooKRUVFHDx4kMzMTHp7exkYGKC1tZUffvgBT09PIiMjUVdX\n56uvvgJep2S7uLhgbm5OcnIy+/btQyaT4e3tTUhICFevXsXZ2RlHR0c0NDTIzs7G2dkZDw8P1q5d\ni6GhIYcPHyYpKYmoqChBIJL7/OW9iqCgICZOnMiZM2coKSlh/vz5ZGdnExYWxk8//URzczNTpkxh\ncHCQuro6ZDIZ9fX1HDt2jKGhIaRSKZMnT6apqYmFCxdSVVXFb7/9hp6eHkZGRhw4cIDu7m4UFRWZ\nMmUKu3btIjs7mxUrVrB9+3ah4ZDTgx4/fiz4nObm5iI4WM4iMDMzo7OzU3A009PTqa6uxsHBQSgh\nh4aGcHBwEGE1tbW1hISECOOSra0tEyZMQEtLi2nTptHW1sYPP/zA2rVryc7OprCwkHnz5tHU1ERs\nbCx6enq4ubmRkZEh0pl27NhBf3+/oHXBa1enpaUlhoaGxMTEMGHCBLq7uwV09v79+1RWVuLq6oqT\nk5PwMRQWFtLR0cGECRMwMjIiIyMDPT09wsPDxTVx8uRJpk+fjqmpKePGjWNgYABVVVUWL16Mi4sL\nFy5cICwsDCcnJ9TV1Xn06BHBwcFYWVnx8uVL0tLSxCYTExPzp6/Hf4pNQSKRsGbNGgFR8fHxQUdH\nh+zsbBwcHDh+/DiTJ09mwoQJvPPOO9jY2DBjxgysrKzw8fFBTU0NfX19fvrpJ0ZGRsT5aWBgAE1N\nTQHehNfNPLnZJjg4WODDu7u7efLkCSYmJhQVFTE4OIiampqAc+jp6VFTUwMg0pLa29upqqri3Llz\n9PT08OLFC3x8fMjL
 y+Ply5fMmTOHOXPm4OfnR2JiIl988QX+/v6EhIQwevRokWz8ySefAK9hMx0d\nHcTExNDR0UFoaCjp6em0t7fz448/iqi8np4eKioqmDZtGo2NjWRkZHDjxg327dsneI89PT2kpaUx\nMDDAw4cPsba2pqioiBMnTmBlZSXyHOREqc7OTrKystDQ0KC+vp579+4RFhaGmpoabm5uDA0NYWlp\nSUVFBatWrRKJUjdv3mRwcJBZs2bR1dXFixcvWLBgAdOnTycnJ0eAR5WUlCgvLxfuSD09PdLS0oiJ\niaG7u5ulS5cCMDIyQlxcHI2Njezbt4+pU6fS399Pa2srrq6ugsS8b98+SkpKyM3NFSIlV1dXAWWV\nl/TysGELCwtmz55NTEwMUqmUqKgotm7diqKiIkuWLGHZsmV89913NDY2YmVlhZ2dHXFxcfT395OT\nk8OFCxfw8vISEytzc3PgNTVMWVkZFRUVnj9/Tl9fH6dOnSIyMhIDAwMsLCzYuHGjqFrlQcVubm7c\nu3dPBMYYGRmhoKDAtWvXAGhqasLY2Jivv/6ae/fuMXbsWIqLi3nw4AEHDhygtLQUc3NzTp8+zePH\nj8nJyWH16tUUFBQwMDAAIEahixYt+g/xFP4pjg+//PLL34KCghg3bhwvXrwgOTmZiIgIced+8uQJ\n27dv5/fff2fTpk1Mnz4dNTU1YZ1WVVWlvr5epPvm5eVx//59li5dKoCsckquVColLS1NYMPkvgWp\nVIpMJuPChQvs2LGD6upqKisr8fHxQUVFhYaGBqysrLh69SoBAQECEXf27FkRLS+32I4fP57h4WHi\n4+NpamoSc3V7e3tiY2P55JNP+PHHHwWgQ548lZSUhKGhIf39/SxbtkyExRgZGVFZWcmoUaME/GPs\n2LHMmzdP3P3b2tqYN28e8fHxWFpa0tfXx4QJE5g5c6Zwb+bl5aGtrU1eXh4pKSniQvr111/ZuXMn\
 nLS0tnD59WmDzKysrqa+vZ/bs2SgqKqKpqcnw8DAuLi7Y2NiIEJ/79++LjebOnTuiR/Pee++JBqCr\nqyuPHj3C399fNC+XLFmCoaEhZWVlXLt2jcLCQqytrYWceNKkSSQnJ4uxaVBQEDt37mTKlClkZWWx\nePFibt68iZaWFkuXLuX48eM4OjpiaGjIyZMnMTU1RVtbmxs3btDQ0EBPTw+NjY04Ojqio6PDH3/8\nwfnz53F0dCQzM5Pg4GAsLS1FY1RXVxd3d3eWLFnC0NAQIyMjpKSkIJVKxWTJ0NCQFStWsH79esaP\nH8/ChQvJyMhg+vTpnD59munTp9PQ0ICpqSkdHR34+vqKI1x5eTmFhYXMmTNHaCRUVVW5d+8eTk5O\nrFq1iuLiYhYuXEhRURFaWlp4enqir69PQUEBPT09RERE0NDQQE1NDVZWViKNSz6iraioICAggCtX\nrlBVVfVff3yQSCSVEonkiUQiyZNIJFn/+JyeRCJJlEgkJf94q/vv/Zz29nb+9re/ceTIEQwNDXFy\nckJTU5Pq6mrS0tI4fPgwBw8eJCIigurqah49esSdO3e4evWq/MFibW1NZGQkGzduxNbWFkCUaZ2d\nnUyePJkdO3bQ2NjIm2++iYeHB8+fP0dbW1uEfMij7q9fv87EiRNRU1MjKiqKSZMmsW3bNmbNmgW8\nliPLqUBr1qxBS0uLuXPnCjYgvB6BWVpa4uHhgbGxMcnJyWRkZODi4kJiYiLKysoiu1EOfPnrX/8K\nwNmzZzl8+DB1dXUMDAyQkpKClZUVCgoK7NmzRzD/CwoKuHfvHioqKnh7e5OUlISHh4cIYH3rrbd4\n9eoVo0eP5sSJE6Snp+Pu7o6ysjIRERF8+umn5OTk8PDhQ5SUlDAyMhLS3rKyMjIzM2lpaSExMZGL\nFy+KANeYmBju3LnDnTt3KC8vJygoiPLyctra2tiwYQMrV66ko6OD9957jz/+
 +ENAWpWUlIiNjWVk\nZARvb2++/fZbtLW1cXd3RyKRAFBaWsr69esJDQ0ViLW2tjYUFBQwNTVFV1eXqVOn0tLSQkxMDF5e\nXqirq1NXV8fEiRMZO3YsN2/exNXVVQS0ACxfvpyRkREmT54sWBJvvfUWc+fOJSsriwkTJrBnzx4a\nGhpYvnw5t27dwtnZmYiICKqqqgRvUiaT0dPTIyZGvb29DA0NoaioSEZGBnPnzmXlypVUVlZiZmaG\nmpoa165dExb+HTt2IJPJSEtL41/+5V/Q19ensrISFxcXSkpKWLNmDfCapyCPCpDJZGRkZPD06VMR\ncOPi4kJdXR2pqakoKiqybNky6urqBMti69atODg4oK2tzW+//SYSrf7M+n/j+BAgk8lc/pUl8xPg\ntkwmswZu/+Pj/+0yNDQkLCyMN954A0VFRZFlWFhYSFFREY8fP+Yvf/kLqqqqgr1vYGBATEyMCCtt\nbW3F2tqa9PR0QV4qLS1FXV2dV69eERsby88//0xERASVlZV8+eWXODg4YGNjI0oxExMTCgoK8PPz\nE558ZWVlVq5cyXfffUdk5OtNNjMzEy8vL+bMmUNTUxPl5eXiCZRHhst7DdHR0fj4+ODn54erq6sQ\nJ8n5EUpKSjg4OACvA3O7u7uZOnUqERERxMTEcOLECebPn8/06dOxtLSku7ubiRMnYmFhwcGDB1m+\nfDmZmZlcv36dzz77jIyMDBH6cu/ePc6cOcPPP/+MsbExK1asELp8JSUlIiMjuXLlCqtXr6akpAQ1\nNTVWrVrFb7/9xsyZM5FKpZSWlqKmpoaenh7bt28nKyuL3bt3s2XLFkFBysjIwNPTk/nz51NYWMjz\n589xcnIS4bJnz57l7NmzTJs2jYkTJ1JfX8+dO3cYM2aMSDbq6+sDEOnaNTU11NfXc+XKFcLCwjAw\nMODQoUOEhYVx8OBBpkyZwurVq/Hw8BBiJWNjY9LS0lB
 SUqK+vp45c+aIub8cnvPo0SMCAgK4fPmy\nuPDLyso4efIky5YtIzc3lw0bNnDlyhUUFBSYPXs21tbWeHl5YWlpiZWVFY2NjULefffuXWxtbbG2\ntmbUqFF8+OGHImDW399fmJTKy8sZO3YshoaG7N69W8BuPTw8sLKyYurUqTg4OPDo0SMAJk6cyL17\n9zh37hxxcXECjSeHrzQ1NfH555+Tm5uLhYUFeXl5KCgoIJPJSEhIEAImS0tLHB0dhQfkz6z/ip5C\nGHDqH++fAub/e9/Q29vL+fPnhQknOTmZ1NRUgW6Xm2k6OzsxMzPj1atXdHR00NfXh7m5OVu3bqWj\nowMHBwcSEhIEZKWlpYXOzk4CAgLQ1tYWJN+HDx9iZ2fHjRs36OzsZMqUKSLKbPXq1Zw5c4by8nLe\nfPNNFixYwOHDhwkPDxdCmKSkJKKjo7l9+zaamppoa2uzfft2Ybu+evUq9fX1NDU1sX//fr744guq\nq6sJCAjg/v37gqDT1NQkkpngtSwbICEhAWNjYw4cOICmpiaXLl3i559/FmKn9PR0AgMD+e677+js\n7GT58uU0Nzdz8eJFVq5cyZ49e1i6dClXr15FT0+PwMBAent7+eGHH0hPT+fp06cCpR8aGsqYMWOo\nr69HUVGRixcvsmjRIo4dO0Z2djbff/89ioqKBAYG0tjYSG1tLa9evSIpKYn8/HxUVVXZv38/o0aN\n4osvvmDGjBki4aqtrY0tW7bg5+fHrFmzSEhIoKenh+7ubhFVv23bNqHSg9d9oMjISCoqKqitrRWj\nQX19fYGXDw0NxcTEhJycHLq6uqiqqhIqVDs7O7Zv3463tzdNTU04OzsDr0d8o0aN4q233kIqR6os\ntgAAIABJREFUlbJ+/XrMzMy4ceMGS5cuxd3dnY6ODh49eoSDgwNdXV0cPnyYBQsWsHbtWjw9PTl0\n6BA3btzg9OnTotH4/fffs2rVKo
 aGhnj27Bnl5eVs3bqVzMxMAgMDeeedd9DS0uLOnTv09vZSUVFB\nSEgIDg4ODA0NkZGRwZMnT0hJSSEoKIgLFy4AMHfuXFxcXAgMDGTcuHEsW7aMuLg4UlNTSUpKYnBw\nEIlEwoYNGzhx4gTZ2dlkZWWhqanJ3LlzuXr1Kj09Pejo6DB16lTRyP0z6z+7KciAJIlEki2RSNb/\n43OGMpms/h/vNwCG/6tvlEgk6yUSSZZEIsnq7+/H3d2dZ8+eUVFRweTJk/Hz86Oqqoq3336bY8eO\nsWjRIi5cuEBoaCh6enr09/dz+fJlcnJy0NTURCqV0tTUxEcffcSHH34IvI6dNzMzIzc3lyVLluDr\n68vHH3+Mmpoa06ZNE1VJQUEB69atE+lRixcvFmaZX3/9ldLSUhHnDTB16lQ0NTUxMzPD0NAQe3t7\nPv30U3788UeqqqqYNm0alZWVODs7Mzw8zMaNG8nNzaWrq4vQ0FBkMpkoLydNmsQbb7wBQFdXF6Wl\npYSFhXHp0iUOHTrEjBkzePfdd3Fzc6OwsJCCggI8PDxQUlIiPT2dO3fukJSUhIaGBoODg+Tk5DBj\nxgz6+vqEz6KpqUmkITU1NXHixAmOHTuGmZkZjx49oqOjg8rKSpEU5e/vL/IL09LSiI6ORklJiYCA\nACZNmoSCggL9/f3IZDLhVty1axeBgYH09/eTlJTE3bt3mTt3LgMDA1y/fp2kpCRGjx5NcXExS5Ys\nEfbfFStWiEh1ABsbG3x9fTEyMhJBrIcOHeLQoUOYmprS3NzM4OAgT58+5dGjR6IxraSkxJMnT1BU\nVGTRokU0NzeLBjG8Pj60t7eTn5+PVCpFXV2do0eP8s477yCTySgpKcHAwICtW7dy/fp1Xrx4wZYt\nWwgODsbQ0JDi4mKBTV+8eLFojNbW1jJr1ixsbW0xMDCgra2NlJQU0tLSRAzf+fPn+dvf/sbChQvF\n/zd+/HhaW
 loYN24c2dnZpKen09/fL9Dx+/fvx8bGRqDbDh06hJubm6gYR0ZGGDVqlDD4bdq0CQMD\nA5qamrh165bQRujo6KCurs6pU6f4s+s/uyn4yGQyFyAEeE8ikfj+63+UvcY6/S+pSjKZLFImk7nL\nZDJ3eQPHwsICIyMjgXc3NDTkzJkzREVFYWhoiIqKCqdOnaK9vZ3Hjx+zadMmEY3+/PlzQkJCOHr0\nqLijy1FecjyWjY0Nq1evBqCkpARdXV0GBwd5/vy5aB7Ju8AjIyM0NzcTFhaGr68vJSUlosx3cnLC\nxsaGBw8ekJaWRmFhIYWFhULQU1lZib+/Pzk5OVy+fJn6+no2bdokxlOtra3U1NTwxhtvUFNTI2b+\njY2N+Pv7C3nqxx9/TE9PD/Hx8WRmZoqUpry8PFJTU7GxscHb25uXL19ib2+Ps7Mzra2tyGQyOjo6\nCA8P5+LFi8LJKY+h++yzzwgJCeH58+cEBwfT39/P8uXL6enpobCwkGfPnhESEoK7uzvm5uZ89913\nYvyZm5uLoaEhLS0taGhoiLQlDw8Poe5UUVHB2NgYd3d3IiMjRZ8lIiICe3t7zM3NCQ8PJzw8XGDj\nd+7cCcCNGzews7PDysoKCwsLCgsL8fX1FT0CeeO3tbUVdXV1jI2NRURdQEAAADt27CA1NVXkX8Lr\nPk1cXJwYvd6+fZtt27Zx+/Zt4SmQj5znzZvH8PAwT58+pbGxEVVVVTw9PdmxYwcHDhzAzc2NxMRE\nAHGM++STT+jo6GDy5Mnk5OTw008/kZSURGxsLJs3b2bHjh2cPHkSVVVV7O3taWxsFEng06dPR1dX\nlxMnTghj2MDAALNnzyYiIoInT56wY8cOWlpaMDQ0JCcnB2dnZzIyMpgxYwbz589n//79KCgoUFJS\nQnp6OsPDwzQ3NwuFZ09Pz5++qP9Tm4JMJqv9x9sm4A/AA2iUSCTGAP942/Tv/RxVVVXOnD
 lDU1MT\nvr6+ZGRkoKamxvbt28nLy8PFxYWbN2/i4uLCb7/9xrhx44iIiODAgQM0NDTg5eWFo6MjH330EStX\nrhTjl3v37vHkyRP6+/sZHBzk119/xdbWVoBYCwoKmD17NkZGRty4cQNlZWVKSkowNDSko6NDQDZW\nrVrFxIkTxcw7JSUFTU1NwsLCaGxsRE1NjePHjwuI7KJFi3B2dsbZ2RltbW0UFBRIT09n/Pjx/PHH\nH0LiKo+jkyswFy5cyIkTJ3jnnXdQVVXlyy+/RFFRkdTUVFasWEFXVxdLly5l3LhxIuUqLi4ONzc3\nKioq0NHR4dWrV4SHh3P//n2qqqoIDw8nNjaW7777jsrKSkxNTVFQUCAuLg5fX1+SkpLo7+8X0mg3\nNzciIyOJjY2loKCAS5cucfXqVaZMmSKi0BMSEnj16hWDg4MirdvCwoLq6mqGhoZQV1fHzc2Nb775\nhmnTpiGVSlm0aBHJycnY2NhQW1tLa2sru3bt4vHjx4wZM4bPPvsMeM2qSElJ4a9//avgGsTFxREa\nGsqkSZPE+butrY329nZKSkr4/fffxciusLCQS5cuCeCvvKfg5eVFSEgIW7ZswdTUFA8PD+F3kfM5\nvv/+e3Jzc+ns7GTTpk00NTWRnJwsEqbz8/MZM2YMqqqqopmtr68vjnp/+ctfePHiBbt27eKbb75h\n1qxZrFu3jgMHDqCvr8/q1atpaGjg2LFjqKqqUlFRgZWVFTo6OgQGBhIeHi5cktra2qxZs4b+/n5U\nVFSorKxk/Pjx7N+/X/SRrKysePbsGdeuXSM4OJj09HSUlJSYM2cOg4ODfPzxx0yaNAlbW1sRA/hn\n1v/jTUEikWhKJBKp/H1gBlAAXAXe+seXvQVc+fd+1qhRo7hy5QqKiop88MEHIg5dHnaRm5tLXV2d\nMP/IMd1KSkoiwjwzM5MDBw6QnJxMVFQU8PoJ+/rrr7GwsKC9vZ2Ag
 ADS09NZtmwZVlZWFBcX8+LF\nCzo6OnB3d2fevHkiHdna2pqAgAB6enpYuXIl7e3taGhoAPDw4UPGjBlDdXU1vr6+BAcHs3HjRioq\nKqiqquLMmTPExMRw7tw5Nm/eTEVFhSBJy2Pu5fr12tpa3NzcgNebjZqaGomJibz99tu4ubnh6enJ\nggULOH36NHZ2drx48YKHDx+KmLu3336buLg4rK2t2bRpE5X/iLwPDQ0lLy+PvLw83n77bTZs2ICr\nqytNTU1s3LiRmTNn8ve//104Drdt20Zvby/x8fG4uLgQGhqKpaUl06dPx8rKiszMTEpLS7G2tmZk\nZITQ0FBCQ0Opqanh8uXLKCoqUlVVJTwgTU1NVFdXC5elq6srkyZNIjw8nMrKShGY8+DBAzGbB/j2\n229FRL21tTWHDh2ira2N48ePY2lpSUtLC19//TW6urrCfi7PogwMDERZWVlUgHp6ehQVFQGvUf6/\n/PILERERvHz5kuzsbB48eCCgvXIIsLu7O+7u7pw6dUrE3nV1dZGSksKqVavQ09MjJiaGM2fOAHD7\n9m2kUik+Pj709/ejo6PDjh07MDY2xsnJiWPHjuHk5ISPjw+VlZX88ccfqKmpCXHX8ePHaWpqorW1\nFQUFBQFZ8fX15fnz5/T39/P06VOys7O5cOECa9as4Y8//sDT05PExESsrKxQVVXl2bNnIh9DT08P\nS0tL7t69i6WlpQDy/tn1n6kUDIGHEonkMZAB3JDJZDeBvUCwRCIpAYL+8fH/drW3twuKsrGxMVlZ\nWfT19WFqaoqtrS3r1q3D1taWffv2YWxsjKGhIYODg3R1dZGbm8uYMWPQ0NDgwIEDODk5oa2tDSBK\nWUNDQzo7O9m9ezdPnz4VfnY3NzdOnDiBj48PVVVV9Pb2oqenR0FBAcPDw1RXV/PBBx9gaGiImpqa\niPX++uuvOX78OE5OTty6dYvq6mpqa2sZO3Ys
 Wlpa2Nvb09rayvr16/n8889ZsmQJJ0+eFIk/FhYW\nIsZLKpUK96W8iz00NERXVxdGRkacP3+evr4+Fi5cyNmzZ7l37x7Ozs4CHvPy5Uv8/PwEkGbDhg10\ndnYSGhqKv78/Q0NDvHjxgoCAAOzt7dHV1UVLS4vY2FjefPNNFi5cyNy5c/nmm294+fIlL168QFVV\nlUOHDmFkZMTAwACxsbHMmTOHc+fOoaWlRX9/P93d3URFRTE8PIyenh61tbWYmJjQ2trK5cuXRcCK\nTCZj3bp1zJw5k6ysLA4fPoyuri7z58+noKBASMzlL9offviBJ0+e4OHhQUZGBrNnz8bGxgZVVVUu\nX77M0aNHRfiPfMNRUVFBR0eH5ORkLCwsWL58OW+88Qa3b99myZIlwGsOqDy89uLFi3h6elJfX8+R\nI0coLS2ltLSUtWvX0t3dTUJCAtbW1hQWFvL5559TVVXFggUL+Pbbb0XFKv99tbW18fb2JjQ0lIyM\nDAYHB1m2bJkYUz98+BAvLy/gderT7Nmz8fX1xdzcnKKiIlasWMGECRMIDQ3l0aNHTJs2DXgdihMc\nHIxUKqWurk6khWVkZDAyMkJeXh4AKioqKCoqoq2tjZeXF6NGjaKnp4f3338fdXV1srKyqKqqQkdH\n509f2P9Dc/6f9T/r/z/rvw/NecKECSxZsgRra2v6+/u5e/cumzZt4saNG5iZmTEwMCCov3PnziU6\nOpr169eTmZlJe3s7WVlZjB49WkA+ZsyYgYODg3DJlZWVkZeXR3NzMxoaGtja2tLX10dxcTGTJ08m\nPz8fe3t7srKyCA4OFtSdsWPHUlBQIGLO/fz80NXV5dy5c0yePJkjR46wbNkyBgcHSUpKYnh4mK6u\nLjZv3szDhw/p7+8XR5aKigoqKytRVlZmyZIlaGtrc+LECQwNDZk1axbe3t7MmzePKVOm4OXlxdDQ\nEOPHjxc25t27d/PXv/4
 VmUxGXFwcioqKoilra2vL3r17mTp1KlOnTuXu3btcuHCBPXv2UF5ejpKS\nEu3t7SKpSh4gs2TJEuLj4/Hw8CAnJweJREJxcTF/+ctfSEhIQE9Pj6GhIX7++WcCAgKEBffo0aNi\nRGZubi7s0/X19Rw9epSNGzdibGyMtrY2P/74o3AtNjY2YmtrS3FxMfX19VhZWaGmpoaBgYFI/UpJ\nSSE7O5uqqirmzp3LtWvXGB4e5tixYyQmJgrvhZ6eHtnZ2YwbN46WlhYSEhJwdnbm2bNn9Pb2oqCg\nII5QW7du5dmzZ9y+fZuamhrc3d2pqalBR0eH4OBgkVvZ0dHB0NCQGEWrqKhw5MgRFi5cyIQJEygt\nLRWTseLiYjZs2EB6ejoNDQ0MDw/T0tJCeXk58+bN4/79+3R0dODn50dBQQG+vr5UV1dTVFQkBFDu\n7u48f/4cCwsLIWYrKytjy5Yt7Nu3jwkTJogJ2osXLwgPD+eHH37A3t6eqqoq7O3taWtrw8LCgri4\nOCEC09DQICcnBx0dHTQ0NOjq6iItLY07d+78qevxn2JTkEgkqKio4O7uTn5+PvPnz+fmzZt0dnbi\n5eVFb28vL168ICgoiN9//x0rKytkMhmZmZlYWloKbkJtbS06OjqizHd1deWbb77B2dkZY2NjPD09\nSUpKIikpiUWLFqGmpkZxcbHwu8tVh/v37ycxMZGysjJiYmKwtbVFUVFRILi0tbWpr68XgSRffvml\noE4rKyvT1NREYmIiO3fu5PLly9jZ2dHS0sLbb78tHoucY1hfX09sbCwA+/btE4GjSkpKHDx4EB8f\nH9avX4+/vz9JSUmcOHGCwcFBzMzMcHZ2RklJSWg0rl27hqmpKWZmZgKccvHiRb766isaGxuRSqUC\nSKKnpydQ4YaGhiQnJ7Njxw4mT54sjlRyBd2ePXvIzs7GxcWFs2fPMmHCBL788ks0NDQIDQ3l+++/\n56
 uvvsLe3h5VVVXS0tLQ1dXl1KlTbN68GVtbW4KDgwkMDCQzMxMjIyNCQ0PJyckhISEBTU1NQkJC\ngNeinRMnTtDV1cWWLVvYtm2baCTfuXOHuLg4oqOjRSNSflRct26d0Px3dXURExODpqameM727duH\njo6OELbZ2tqSmprK8+fPqaysRFdXV/hb9u7dy+nTp9m3bx93796ls7NTxLClpqZy8uRJMS3p7+/H\n0dGRoaEh7t27J0aMAQEBwtIeEhLCw4cPcXZ2Ji4uDisrK2bNmoWSkhJWVlYCpV9RUcHYsWMBRECP\njo4Ourq6IoTH0dGRKVOm0N/fj0QiQVlZmZqaGt566y0iIyOpr69n3rx5ODo6IpPJ+Oabb5g5c6Yg\nbf+Z9U/hffjuu+/+NmvWLKqrq/Hw8CA/Px9NTU0mTJhAUlIS06ZNEyo9+eaho6Mj0pLb29sFBn7q\n1Kl8//333L17Fzc3N/z9/amsrMTJyYlPPvmE5uZmGhsbcXNzY8yYMWIaYGVlxdGjR0UWoPwuZ2Fh\nIeAY1dXVpKamilTjd999l6ioKBYsWEB1dTV2dna8fPkSBQUFGhoaqKqqYuPGjQKv1draSkdHB1On\nTuXp06dMmjQJHR0dGhsbuX//vgjTBcQTLo8ck1+4Bw4cICgoiLFjx6Kurs7YsWNJSEhg8uTJuLi4\nEBUVJRqxoaGhdHV14e3tTXR0NJs2baKkpITKykpkMpm4wz948IDu7m4kEgllZWWMjIxgaGhIXl4e\nMTExyGQybGxsBBovKSkJW1tbpk6dSlFREYsXL+bq1auMHz+e7u5u2tvbGT16NIaGhgwPD2NqaoqD\ngwMBAQFUVFRgb2/P5cuX8fHxQUtLCwMDA9rb2wWP08DAACMjI5YuXYqWlhZXrlxBU1MTGxsbAgMD\nhWHN2dlZODi//PJLmpubGT9+POPGjaO6uprly5eTmJjI48ePMTAwEM3ZBw8esHb
 tWvr6+igpKWH6\n9OmYmJgwatQoDA0NOXjwIKqqqlRXV9Pd3Y2JiQnLly8nOzubzs5OQkJCyM3NJScnh3Xr1nHz5k2U\nlJRoaWlBVVWVUaNGUVFRQU5ODtnZ2TQ1NeHu7i6CX3t6enjy5AlNTU0cOnSIjz76iNWrV1NdXU1J\nSQmpqakYGBgQERGBnZ0dBw8eJD09neTkZMaOHcvYsWN58uQJfn5+Ikk7Li6ODz74gJcvXzJ69Ghq\nampobm7m+++/R+3/Yu+9orK6+r3t66b3DtJ7kV4sgCh2LEQBe0ej0VRNfHzUFJMYjSaWFI1JjL1i\n7w0FQZQqHaWL9M4tvZfvwH3P8e7vZOfgHd/IM769TjLURMkta665/vP3uy4VFW7dukV2dvbf6j78\nIxaFnTt3fhsQEMDs2bNJS0ujqKiIV69eIScnh4aGhtCVWVhYcPv2bdTV1dHT08PDw4Oqqiqsra3J\nz8/Hw8ND1JplgtT29nYyMzPR1NQkICCA0NBQQT/67bffCAwMZNq0aaSkpDA0NMS7774rqrQqKiqo\nqakhkUjo7+/HxMSE+/fv891339HY2IiCggIjRozgwYMHGBgYoKamRlNTE56enri4uFBfX4+xsbEA\nkwwMDAiwiuwV4c2bN5iYmHDlyhVcXV3p7Ozk8ePHgg48f/58oZeXJeliYmKYPn066urqxMXFMW3a\nNJSUlLCyssLNzQ0LCwuMjY1JT0+nq6tLYOj09PRobm6mvr4eGxsbSktLxRNKT08PZWVl+vr6kEql\nWFtbU19fz6pVq4SebnBwkKamJiZOnEhubi7FxcV88cUXHD16lPHjx/PJJ5/w/vvvc+bMGVauXImh\noSERERFIJBJ6e3vJzc1lzJgxuLq6oqGhgYKCAk+ePBFW58jISMLDw1FXV2f48OFcv36dpqYmTExM\nePLkieAhyIalp06dYt26dWhqagol/KxZs1i3bp1IH8rweP
 v376e8vFzkQ2JjY/Hy8hIMiP7+fmpq\nalBTU8PAwABfX1+UlZWJjo7m0aNHGBsbo6Ojg7W1Nd3d3bx69Yrc3Fw8PT3R0dFh5MiRwvHY09PD\n7Nmzha6tsrKSuLg4gdiTsSNfvnzJ7t27mT9/PlpaWujo6LBw4UL27NnD4OAgo0eP5tdffxUnQGZm\nZkgkEmpqapgwYQKxsbEYGBiIIWNmZiYODg5YWlqSnp7OggUL0NDQoKKiAkdHR65cufKfw1OQSCTI\nyclx9epVuru70dTUZMKECRgZGbFr1y76+voETfnQoUOoqamho6PDn3/+iZeXF25ubigqKgrh5uvX\nr4G3AaWIiAh6enqor68nNTWVnJwcJk+eTEZGBu+99x4xMTEYGxuLbXtRUZFYcPT19SkpKSEwMJCP\nPvoIa2trAMF0vHHjBrt370ZNTU2c6b98+ZK//vqL/v5+DAwMOH/+PFFRUaioqKCsrCy05DExMTx4\n8ABLS0uRU1i0aBGtra1MmzaNhIQEUlJSePjwIaampkRERLBw4UJev36NtbU1pqamPH/+XJCkVFVV\nBfe/qamJnp4enj9/joGBAePGjUMikbBlyxZevnzJBx98gKurK9ra2nzyySfs2rWLoKAgAgIC6Ozs\nxN7eHm9vb1xcXOjs7KS0tJTa2lqSkpLw8PDgxx9/ZOnSpcjJybF69WoWLFjAq1evCA0N5dixY/z8\n888kJyfz6NEjHBwcGDVqFFlZWRgaGtLX1ycIVc7OzlhaWqKnpyeELrIkZXFxMSNHjqSxsZHo6Gje\nffddAWnNzMykuroaOzs7IiMjOXXqFE5OTmzZsoVhw4axcuVKGhoaBLIM4PLly+jo6DA0NERhYSHm\n5ubk5uZibW2NgYEBcnJy+Pr6iqZiamoqXV1dzJgxg/DwcOzt7UlOTiYzM5OhoSFhIFdUVCQpKYmV\nK1dSVlZGZ2cnx44d4/Tp09y4cUPIi
 Hx9fYXcxdTUFBcXF1xcXMjIyBCwGSsrK3GEunnzZrKysli0\naBGZmZkYGhpiYGCAnZ0dbm5uJCYmMn78eLFYvXjxguHDh4uC1pIlS0hOTiYjI0N8z/zd6x+xKCgp\nKfHq1SvxNJXlA0pLS3n48CFWVlaCTFxcXIy3tzfFxcU0NjbS19fHnj17RMRWVVVVHPf9+OOPmJqa\nMjQ0xJgxY2hra0NbW5uIiAh0dHTIy8vDzc2NnTt3CpCmrq4uRkZGJCcn09HRwYwZMzh69ChpaWnc\nvPk2crF+/XqMjY0JCwsTVVhvb28sLS357bffxDGRLE+wdOlS9PX1ef36Na9fvxYpSW9vb5H5h7ff\nYA0NDcTHxzN9+nTeeecdgoKCKCkpEQQq2ZD0wIEDwgwt2xEcOXKE4OBg9u/fz4MHD9DT0+P27dvM\nmDFDGJRnzJjBkSNHKC4upr+/n8OHD7Nnzx709fVpaWnBzMyMiooKVq1aRXNzM7GxsSIsM3r0aBIT\nE8nJyWHUqFHY2dkJIlVnZyf379/nvffeo7a2lra2NiHsiY+Pp7u7m3v37vH69WuUlJS4fv06VVVV\neHh4cPLkSQEW1dDQIDU1VZCuZU3Wnp4eYZJubW3l/fffp6ysTJi/y8vLuXnzJo6OjpiamqKpqSkC\nVYAA7Jw8eRJjY2PGjh1LZ2cn77zzDsbGxtTW1vL8+XMcHR0F4l+WbZk2bZoYGspQcTo6OuLvLSgo\nCD8/P3777Tfk5OTYsWMH/v7+Yra1ZcsWxowZI2ZbAwMDZGdnC4hMUlISvb29PHz4UGRhfH19RT6i\nrq6OvLw82trayM/PJzk5GX19fSoqKlBXVycyMpLMzEyOHj2KgoICGhoa9Pf3M2nSJBGplj0o/871\nj1gUlJWVRU+/qalJDPnCwsKEtk1XV5f6+nqSk5NJTExEQ0NDxHhXr17N0NAQvb29mJubk5SUBLwd\nWvn6+grElqWl
 Jbt27eLmzZtYWVmhqKiIvr4+gYGBpKamip67ra0tn332GaGhoSQlJQnEmqWlJQB/\n/PGHiBTLMuxRUVH4+/vz4MEDfH19cXd357333uP+/ftERUWRkJCAi4sLurq6nD59mtbWVlFD7u/v\nB976JLq6urh48SLwlldYV1dHU1MTkyZNwsTEhKSkJDFoSk9P59SpU/T29lJfX09aWhoDAwMEBgby\n8ccfC4rPhx9+SHp6OtOmTSM5ORktLS1GjBiBsrIyc+bMQVFRkbi4OPH7DA4OsnXrVpydnTExMRHF\npCdPnqCvr8+FCxf497//TWxsLCYmJgwNDfH06VPWrl1LfHw8z58/x8HBAWNjY8aNG8fx48dZunQp\na9euRV1dnR07djB8+HDk5OSIjo7G0tJS3GRRUVF0dHQwatQoOjs7uXr1KuvXr+fq1atCjFNcXMzF\nixc5evQoy5Ytw8nJCT09PVxcXFiyZIlIUVZWVlJZWQm8HQ7LdjqygXNAQAB5eXnCEqanp0d8fDzl\n5eX89NNPNDc309PTw4MHD6isrEQikaCqqsrx48dFYzY5Ofm/ZV6cnJx48OAB4eHh5OTkkJ6ezrFj\nxxgYGMDKyoqLFy8yceJE1NTUePbsGUNDQxgaGnLkyBGmTp0qPofo6GhMTEzQ09PD3t6e9PR08Roz\nfvx4gZv77bffqKur45133mHWrFk0NDTw7NkzBgYGeP/99xkaGhLszr97/SMWBTU1NYKCgmhsbMTQ\n0JClS5dSUVEh3kUB0ceX4dVk8g2ZuScvL09wAteufdvNysnJEbiyCxcu8ODBA0JCQggNDUVXV5eY\nmBjU1dVJTU1lzpw55OTkiGm0LJCjq6uLj48PZmZmYiu6detWUlJSaGtrE60/We+/u7sbU1NTkpOT\n6ezspKamRvweHR0dmJubU1VVRXt7OwYGBlhZWVFXVwe8pe0ATJo0idraWnbu3CkcClu2bKG/v
 5/t\n27fz4sULwsPDWbFiBRs2bMDIyIgLFy4QGBgo6EG5ubl0dXVRVVVFfn4+LS0tFBYWoquri7u7O4OD\ngzQ2NrJ37142btxIfn6+KBCNGTOGrq4uioqKePnypRikhYaGUlFRIUJY48aNw8zMjEPTGRVJAAAg\nAElEQVSHDrF48WIUFBQwMDDg8ePHXLt2DQsLC65du8bHH3+MlZUVZ8+eRU9Pj7Vr19Lb28vg4CBa\nWlpcv36dKVOmAG+boj4+Ptja2jJx4kRu3bpFUlISH3/8MS0tLXzzzTfMmDEDExMTfv31V27evMn8\n+fN5/fo1FhYWjB49mjNnzhAXF8ebN2/w9/cHECG2kJAQYmJiqKur48CBA1y6dAk9PT1Wr16NsrKy\nEOJs3boVPT09Dhw4QHd3N+fPnycyMpKWlhYSEhIID38b2p0+fTpPnz7F19eX/Px8Dh48yL59+/j4\n44+ZPXs2U6ZM4d///jdWVlZ0dXWxdOlSjh07hrW1tfCYPH/+nFOnTqGlpUV1dTWAkB319/czbtw4\nzM3NmTdvHkpKSmKXIZFICAoKwtXVla+//pq2tjZyc3OxtLQkOjqaCRMm8OTJE+rr68Ux9N+5/hGL\nQm9vL0VFRRQUFODq6kphYSFbtmzh7t27Aqfu7u5Odna2gGAODg6SlZUlYBN3794lLy+PyZMnc/fu\nXeAtJjsnJ4fr16/j7OwsDNZ9fX2iXpybmysm3oDgAX777bd0dXUxcuRITp48SVVVlWjyVVRU0N/f\nT1NTk/jaPTw8SExMFH2JsrIypFIpc+bMQUdHRxiGZGqw3t5ezp8/T1xcnNiB2NvbY25uTkBAAHp6\nepSVldHU1ERHR4dgSaiqqlJbWyuy+B0dHRgYGHDx4kVsbGz45ZdfGDt2LNXV1fT399Pe3i7EKVpa\nWrS1tWFqaoq2tjYzZ87Ex8eHO3fuYGVlxbNnz0TOXmbm/vHHH+nt7cXL
 ywtLS0s8PT3JycnBwcFB\nlKji4+P59NNP6erq4uHDh6SnpzNy5EgOHjzIyZMn6erq4vfff2fDhg1oamqSnp4uRDKzZs2isbFR\nHN8VFxdTVVXFhQsXePr0KaNHj6auro47d+4wfPhwNmzYQE9PD7q6uvj7+5OWlsbLly+xs7MTngcZ\nc8PExISEhATxfSaLUxsYGODu7s6sWbNoaWlBU1OTvLw8qqqqSE5O5uLFiygrK5Obm4uVlRUeHh4C\niCKbc8k6Cl5eXpibm/P06VNKSkrYtm0b169fx8bGhrVr15Kfn09KSgo3b95k3Lhx3L17Fx8fH0pK\nSujp6UFfX5+VK1eSkZHBvn37hM+kra0NKysrRo8eTVZWFmFhYbi7u1NTU0NzczP5+fm4urqSlpbG\nTz/9hLu7O729vSxatAgZBFleXh4DAwOSk5MFr+LvXP+IReHNmzciH/7nn39iYWFBX18fo0aNIiIi\ngrq6OlJTU5kyZQqTJk0CwMnJCVdXV2JjY0lKSmLLli1UVVURFxdHUFAQAK9evaK0tJQ1a9agpqZG\nb28vbm5u2Nra8tVXX5GRkYGCggLZ2dk8fvyY8PBwXr9+jVQqZebMmZiZmZGfn8/nn3/OoUOHxJl3\nQkICDQ0Ngm68fv16EhMTsbe3p6Ojg9GjRzNp0iSRv8/IyMDS0pJ169aRmJgo/IIfffQRnp6eYrjU\n3t7OxIkTUVFR4c2bNzx79oxr166Jp7vsiGzbtm10dXXh4uLC3bt3qaqq4tKlS7x69YqSkhI0NDQE\nICU4OBhvb2/k5OSIiYlBRUWFq1evcuLECaKiorC2tkZPTw8nJye2b9+OmZmZwM7p6upy4cIFampq\nuHfvnhCbyt5lT548SVRUFKtXr8bExISOjg5Wr17N9evXkUqlnDhxgo6ODuTl5dm2bRuRkZEcP36c\nxsZGrly5wsaNGykqKmLWrFkC8V5aWsrcuXPp7Ox
 k2LBhxMbGIi8vj5mZGQ4ODjx69IjBwUFu3brF\n8+fPxSumg4MD1dXVgq4sw87LtuMeHh7MmDGD5ORkWltbUVRU5PXr16J9mZubK7Drr1+/5s2bNygq\nKhIZGUlkZCRv3rxhcHCQ9vZ2KioqmDZtGgAXL14UJjGpVEplZSVycnJ0dXXx7rvvoq2tTX5+PjNn\nzuTrr7/Gy8sLDQ0NmpubBR6vpKSEzZs3Y2lpKR4Q8DYD4erqip2dHT09PTx+/JiamhqmTp3K8OHD\nUVBQYMaMGXz33XeEhIRQXFxMfn4++/fvJz8/n/7+fqRSKePGjfvPGzTK5CwSiYRp06aRk5PDsGHD\nsLS0JCQkRNiN09PT6evrY9myZSQnJwt3Y1dXF+3t7Xz00Uf09vYK9ZesNSjTn0VHR6OkpERNTQ1f\nfPEFAwMDzJo1S/Dz//rrLxoaGkSnoLGxEScnJ65fv8769esFun327NmYmJhgZmbGq1ev0NHRYfjw\n4URERBAaGip05IaGhrx48YLy8nKmTZtGbm4u3d3dbNy4EQcHBzIzM8UQEd4mO3V0dAQxZ/Xq1ejo\n6AjKsOyo9eDBg1hYWJCfn8/q1av59ddfOXv2rLAaVVVVUV5eLgCxWVlZxMXFce3aNRITE9m1axeu\nrq5kZWXR1dUleJXXr18nKSkJb29vQkNDycvLIzQ0lHv37nH48GFaW1sZN24c27dvZ3BwkIULF3L1\n6lVWrlyJu7s7jx494vTp0zx//hwPDw8+/fRTbt26hbm5Obdu3cLFxUUMds3NzVm+fLkQ6sp2CmPH\njuXIkSOcPHkSRUVFOjs7hYn8q6++EqbwqVOnoq+vj5+fH05OTnz33XcAQsySnZ2Nvr6+qFMrKiry\n5s0bFi5ciIKCAocOHcLAwABlZWVevHiBhoYGnZ2djBs3joyMDPT09HB1deWTTz7B09OTtLQ07Ozs\nKCwsRFFRkcuXLwNvW53Nzc
 1CLqSlpUVrayudnZ309PRQVFQk/JFubm6kpKRw79498YApKipCIpFw\n//59IQoGRKfj8ePHHDp0iOLiYvr6+tDR0eHIkSMkJiZy9uxZ4uPjefPmDVVVVTg4OPDDDz+I4XdR\nUZE4+v3/rDr9f+uSSqXk5uaKbeXmzZu5fPky1dXVGBsbM2zYMAICAsjNzSUtLY2rV6/i7u7O5MmT\nBdrMwMCAM2fOiAANIIAnUqmU3t5exowZg42NDcXFxYwZM4aQkBAcHByorKwkMzMTOzs7wsPDiYyM\nxMDAgMbGRlxcXBgxYgQVFRViaPXXX3+RnZ1NRUWFkH729/cjJyeHh4cHs2bNQk1NDXV1dRoaGvjX\nv/4lpK4lJSUkJCRQXl4ujkcfP34MvCVFFRQUkJCQIBaHMWPGkJOTQ2dnJ46OjlRXV6OgoMDt27dF\nkWvXrl18/fXXqKiosG3bNu7duyd8Bbm5ucyaNQsvLy82bdpEYGAgO3bsoKamBnNzc0G3evz4sTgr\nb2lpobW1FRsbG6Kioli2bBlLliyhq6uLmJgYFi1aRGFhIQkJCRw5ckTUyH/55Rd+/PFHgoODMTc3\nZ86cOVy4cIHU1FRKSkqwtbWls7OT8PBwampqMDQ0pKWlBTk5ObEwyo7qbt26RUNDA9bW1jx69Ahv\nb29Onz6NmZkZxsbG4vXg4MGDKCoqMmbMGJydnUVbcOTIkWJGBAg4zZMnT7C1tRXhL319fZYtW8bc\nuXPx8/Pj+++/Z9GiRSgoKGBhYUFUVJSQ+2ZnZ7Nu3TpxGgZvS061tbWinizDtJeXl1NXV4eBgQFT\npkwhPz8fOTk5Fi9eTGtrK6mpqSxevJjc3FyUlJSIjIxEUVGRpqYm4K2FbNiwYSQlJbFz5076+voI\nCgoSeIGWlhaCgoJYunQp69at48qVK4wcOZLBwUGSkpJ48OABzs7OBAUFcfHiRY4fP/6378d/xKKg\nqqpKY
 GAgEyZM4M2bN6xbt46pU6diaGhIXl4e8vLywv3o7OyMm5sbNjY2dHZ2kpycTGBgIJmZmejo\n6BAfHy9sOPPmzSMjI4OioiKBj5dhuAcHB8nLy+P3339n2bJlLFu2DAsLCxwdHVm7di0KCgp0d3ez\nd+9eKioqaGpq4tChQwCMHz8eU1NTKioq2Lhxo5DGbN++nWfPnmFjY8POnTvR0dEhMDCQ2NhYFixY\nIMjNssVl9uzZQkAKbxuTGhoa7N27FxcXFy5evEh0dDQuLi5MnjyZ2NhYFi9ejJKSkug1mJiYiNcD\niUTCpEmTyM3NRUtLi/r6ej766CMePnzImDFjBMfyyZMnwl587do1HBwchF7ew8OD9PR0zp07h7+/\nPyoqKlhbWxMcHExYWBgdHR2cOXMGNTU1JkyYwOHDhzl9+jT9/f1s3LiRhIQEoqOj0dHRITU1VaRR\nGxsbefDgAR9//LHA3CcmJlJUVERra6s4Rq6srERVVZWUlBTU1dWZO3cuU6dOpbGxkc2bNwuega7u\nWx6ws7MzmpqajBw5kqioKDQ0NEhJSaG7u5v4+Hg+/PBD4O0JV1tbm+gf+Pv7k5+fz9SpU8XN39XV\nJQC8RkZGvHr1iv7+flxdXcXJxIYNGzh79qwA+dTX16Ourk5ubi4mJiYcOnSIFStWUFZWJsxexsbG\n3Lp1i6lTp5KRkcGECRNE98HOzo7m5mZZ4lBg3nJycqitrRVtTUtLS06fPo2qqira2to8e/YMOTk5\n0tLSWL58OX/99Rft7e3cu3ePTZs2oa6ujoKCAtbW1igpKQm3yN+5/hGJxl9//fXblStXEhkZibOz\nM9XV1ZSXl1NfX09hYSEKCgqYmZkxd+5cEhISKCoqwsjISABCPD09iY6OFufH7e3tAm/l7+8vCjl2\ndnY8ffqU9957T/z4/PnzuLi48PTpU2EUkrEENTU1Wbp0KTExMZSVlXHgwAEOHz6Mtb
 U1zs7O4kTB\n29sbJycnoQF7/Pgxra2t5Ofn4+Xlhb6+Pjo6OlRUVFBVVYW+vj6mpqYCkLp//35B4T1w4AAVFRW8\nefMGd3d3nJ2diYiIoL6+noCAAIaGhlBQUBCkqGPHjqGnp8f9+/fR0NBg1KhRdHd3o6uri4uLC2vW\nrOHTTz8Vw7r+/n48PT2xsLBAVVWV0tJSAUcJCwvj8uXLDAwM4OfnR0pKCgcPHhR+wv379zNlyhRe\nvXpFQ0MD2dnZpKamYmNjQ19fH25ubjx69IiysjLu3LmDhYUFHh4eDB8+nMbGRuzt7Xnz5g2XLl1i\naGiItLQ0xo4di1QqRVNTk0uXLrFp0yZBpzI2NiYvLw81NTXi4+OFnOXy5cuoq6ujra0t8Gp79uxh\nzJgxFBUV0dzczNDQECEhIYwcOZLIyEimT59OTk4Ompqaok8go0zFxcWhqqrKkydP6OjowNraWnzW\nenp6mJqasmvXLoYNG8bEiRPp6+tDS0uL2NhYlixZIjQD169fZ8KECcjLy7N27VrOnj2Ln58fxcXF\nGBkZiRM0BwcHLl26RHBwMI2NjYwfPx5VVVVaW1vFQnvlyhU0NTXp7OwkKSmJwMBAlixZIujPM2fO\nJDU1lZiYGObNm8emTZvw9/dnyZIltLe3o62tzdy5c4mKiqK7u5vp06fz888//+fEnA8fPvytv78/\nbW1tpKenY2VlRVVVFYqKikLcCYgyka2tLRUVFcybNw87Oztu377N3LlzxbR4+vTpHDhwAH9/f+rq\n6oiJiSE7O1tswTIzM3F1dRVUY1kwJz09XVCPb926RWhoKGvWrBEJwJ6eHk6ePMmhQ4doaGggJiaG\nUaNGoaWlxblz57C2tubx48diIRs9ejSRkZGYmJjQ3d3N+PHjsbKyQiKRoKWlJTDz9vb2REZGMmLE\nCD788EMRUx03bhxlZWUoKCgwbtw4TE1NGTZsmADX+vv74+Dgw
 J9//klnZyddXV20tLQwMDCAmZkZ\nd+/e5V//+hfR0dEiGhwQEMCoUaOoqqoiMTGRd955B39/f+7evUtFRQVLly5FU1OTtrY23N3dmThx\notjRrFq1CgMDA+7fv4+WlpbgTY4ePVo4GFRUVHB0dGTatGnY2NgIsU1oaCjd3d2UlJRQVlZGbGws\ntra25OTkoKCgwJgxYzhy5AhfffUVxcXFmJqaUlxcjJaWFn/++SchISEYGxuLVqRs6z9hwgTOnTuH\nk5MT+vr6BAcHU1hYyLx583j9+jWqqqrcuHFD7HJkn016ejrz5s0jIiKCJUuWCKeosbExlZWV1NbW\ncvXqVWTfl66urixevFhwM+rr60lJScHV1ZUpU6YQERHBsmXL2Lt3LyNGjODQoUN89NFHDBs2DFNT\nU6ysrEhJSRFJzP7+fgHQff78Oerq6uKoPSkpCVVVVdHN0dXVZebMmXzwwQeUlJTQ19eHo6OjGGYa\nGhoyceJEGhsbmTt3Ln19fQQHB3Pt2jUWLFhAbW2tjHPxnxNzlkqlQre2evVqXr16xYwZM8QW38bG\nhrt374qZwaRJk1i8eDHnzp1DTk4OW1tbnj17hlQqJS0tjdraWuDt1tLQ0JBJkybxzjvvUF1djaKi\nIlKplPz8fDo7O5FIJOzcuVNM6mWuABmA85tvvqG1tZWenh6BYysvLxcBqaSkJC5dukRDQwORkZGi\nobZ06VJsbW2ZNWsWQUFBFBQU8OTJEw4fPoyRkRHFxcWUlZWJjgIgGpYysk53d/d/u8FDQkIIDw9H\nXl4eCwsLXrx4QUFBAd9//z3//ve/UVdXp7a2ltmzZws0u7y8PDNnziQzM5Pp06cLIpSenp7wF27f\nvp0JEyYQGBhIcnIyERERmJqaUlpaSk5ODl1dXcK5cfr0aZE+TEpKEl7JzZs3s3XrVuGQ/PXXX1FW\nVmbFihViEPzkyRN0dHTo7+9n06ZNDBs2
 jDVr1vD+++8THR0NvB3cWVpa0traioKCAq9fv8bd3Z2S\nkhLU1NTYtm0bkyZNEgGk27dv8+677xIaGiqekB0dHVy7do158+Yh44XIy8uL9/Suri6kUiljxoxh\nypQpHD58WGy1VVVVsbGxITs7m6CgIF6+fCm6ITk5OXR3dzNz5kwB221paREi2EePHhEUFISioiLB\nwcEoKysLpWFHRwcLFixg9OjRXLp0CXV1dSZPnoxEImFwcJDq6mqqqqoEaPb7779HWVlZgHJv3brF\nO++8g5ubmzgWtrGxYc+ePQIfYG9vT0pKCo2Njairq7NgwQIxYJVBh//O9Y9YFGQ8OnV1df766y9a\nWlpITEykoqKC5cuXo6mpiYWFhfDwVVdXU1xcjKenJ2pqahgZGWFiYoKpqSnjx48XmvCmpiYyMzPp\n7+/n6tWrQmXu5+eHo6MjcXFxjBs3TvyatrY2YWFhZGVlYW1tjYmJCba2tkilUi5evEh2drb4ekNC\nQhg2bJjI5y9duhRtbW327NlDXV0d7e3tvHjxgri4OFJTU2loaMDMzEwIX2VwV5nHUnZJpVJ0dXXJ\nzs6moaGBgIAAYmJihPZs0aJFDA0NcerUKfz8/ETMVUNDQyDvY2NjgbenOtevXyc+Pp7Lly+Tl5dH\ndXU1Y8eOxdraWqTvVFVVUVdXJzExkfLychYuXEhhYSEBAQE4ODiQnp7OtWvXMDc3R1tbGwcHByFD\ncXR0xNPTk3fffVeQin18fAgNDSUhIQFlZWV++OEHQU/q7e3lxYsXTJ8+nUWLFvHo0SMKCgrEsFUG\ncu3o6KCsrEzIdoqKioTVuampiXv37uHt7Y29vT2XLl0iLy8PJycn4uPjqampISwsjLVr12JrawtA\na2srJSUlJCcni+PsP/74g6CgIGxtbSkrK0NeXp7q6mqkUiklJSVYWVmRkJCAnZ0d0dHRQvv+9OlT\nrly5AoCbmxsDAwO
 CVTl8+HA8PDwwMTFh6dKlWFpaUlJSQmVlJV988QXR0dEsXLiQefPmceLECdTV\n1cnLy0MqlYpXToDt27fj5OTE0NAQy5Yt49ChQ0RHR5OVlUVNTQ1ubm48efKEYcOGsXPnTvHgWrhw\nIRKJhKdPn3Lp0iWio6MZP348EyZM+Nv34z9iUejo6EAqlaKnp4eWlhYODg6kpqaKTnh1dTV6enrE\nxcXR0dGBmpoaqampWFhYUF5eLo6TZGKXlJQUAOED0NLSYvr06eTn55OdnU18fDydnZ388ssv5OXl\nYWBgwLJly9DQ0OCnn37CwcEBVVVVMjIy6OjoENtRGdJKQ0OD5ORkdHV1iYuLY+3atfzyyy8i2+Dm\n5kZHRwcvXrxAXV2dR48eiS2/tbU1T58+ZezYsQIBLsN66+vrY25uzrJly4iLi8PQ0JCenh6mTZsm\ngl1z5szhypUr7Nq1i8rKSgwNDYmPj6e9vR1LS0vhiNTS0iIsLIxFixaRmJiIjY0N9fX14pjyr7/+\nYtGiRRgYGAiVWk5ODlpaWtTV1dHQ0CCOtUxNTbG1tSU/P5+MjAyys7NJSEjg5cuXFBcXo6SkxO7d\nu1m5ciV+fn7ExMRQX19PcHAwd+7cYcWKFXz44Yf4+/sLj0dERARHjhyhvb2drKwsZs+eDcCqVat4\n9uwZvr6+2NjY8PLlS06ePElnZyfV1dWMGzeOwcFBXFxciIyMZM6cORgZGWFtbc25c+dQUVHh008/\nRSqVCo4BvF3IZUYuLS0tBgcH8fLywtPTk76+PgYGBujt7UVFRYXm5mZWrVrFq1evmDt3Lnp6ekgk\nEvz8/JCTk0NdXZ33338fACMjI1xcXDh48CCjR4/m9u3blJSUcPz4cT788EMCAgIYMWIEvr6+rF+/\nnvfff5+ioiJOnDiBkpIShoaGREVFUV5eTnV1NQsXLgTeypGfPn2KRCLh0KFDLFu2jEWLFjFhwgSh
 \ntNfR0cHX15cDBw4gJydHRkYGn376KWpqasJ90t3dzeXLlwW39O9c/4iZwq5du751cnJCQ0MDRUVF\nLCwsyMvLw97enpaWFhwdHTE2Nqa9vV1k4jMyMvD29qa3txcDAwN6e3vR0tLi4cOHfP311+zbt094\nFfr7+yksLERbW1uQiGRR5uzsbKysrCgpKeHzzz/nl19+EVVrDQ0N9PT0mDFjBvHx8RQUFJCeni6c\nl8rKylRUVKChoSHqswMDA6IrYWRkRGNjI5MnT6a3t/e/vSbIXg9OnTqFvr4+cXFxjBw5EmdnZ2pq\nakROwtfXl6ysLLy9vcnPz0cikaCiokJVVRWpqakMDg4SFhZGaWkpGRkZuLq60t7ejqamJtevXxdH\nfkFBQWIBLS8vF9VtHx8fwsPD2bJlC6ampnR0dPDee+9hbm7O2bNnOXDgADdu3BCNSRk7Ul9fHw8P\nDxYtWiREqTKdm2ygOjAwIE4SvLy8xDt9f38/tbW14skWFRWFqakp9+7dQ0tLi5cvX+Li4oKrqyvZ\n2dls2LBBlMVkx8uRkZF8/fXXpKWlYWNjg4WFBTNnzmTHjh34+PigqKjItWvXxPHmtGnTxILp6+uL\ntrY2XV1dXL16VbhAX7x4IUS6b968wcbGhjFjxlBZWSk+x87OTszNzXnx4gWJiYmMHTuWqqoqvvzy\nSzE4vXr1KgsWLMDCwoKSkhISExN58uQJWlpauLq6kpCQQG1tLcuWLaO4uJiZM2eK1+K7d++SlJTE\nN998I4J5W7duFacdSkpKjBgxgt9//x1zc3N6enq4e/cu9vb2NDc3Y2lpKeA3RkZGjBgxghs3bsji\n1P85MwVNTU2xDe7r6yM/P1/w7t+8eSNquyNGjBDv/IGBgbx48YLKykpx1isrDv3ww1tW7Pz58wWk\nNTQ0FHl5eeTl5YG34ZDOzk5hEk5ISGDLli1ERUURFxcnbuYHDx5w+fJl2tr
 aBC5cVVUVS0tLVqxY\ngY6ODj4+PnR1dfH8+XO6u7uJiIjg3r177NixAxMTEzIzM1FSUsLHxweJREJraysbN27E399f9Obh\n7VPn8uXLPH78WCjbjxw5QkFBAWVlZWhpaYlSkry8PFOnTuVf//oXhw4dor6+nh07dqCjo0Nra6ug\nBSkrKxMaGoqcnBzOzs74+flRWlrKpUuXOHbsGBcvXuTChQsUFxfj7OxMSEgIBQUFZGZmChaBLHXX\n399PV1cXx44dIyoqChsbG2GGHhwcFCErLy8v7O3tuXHjBmZmZmLeYWNjg7a2NqWlpSJLcPnyZUxM\nTERfZcKECSxfvpy+vj4MDQ0ZPnw4J06c4MSJE8ycOZPOzk6ePHmCn58fysrKZGVl0d3dze7du/nt\nt98YO3asgLbIhL/wVk1oYGBAWVkZ165d4+DBgwKxHxMTQ2FhoQDnVlVVIZFImDp1Ki9fvqS0tFRQ\nulatWkVlZSWJiYnA2/lSb28vX3zxBQkJCXz//fesXLmSsWPH0t3dTVZWFkpKSnh4eFBZWcmff/5J\ndXU1M2bMID09nfj4eDw8PEhOTiY2NlbsFH777TeUlZWxsLDg8uXL2Nra4u7ujr6+PteuXePkyZOY\nmJiIY0stLS26u7uFsb2mpobs7Gyys7OZNWuW2I3+nesfsVM4evTotyEhIcyePVtw9FtbW8WWqqur\nS9BsIiIimD17tgj0yJ64hYWFAmoRHx9PZmYmP/zwA7dv3xbb39TUVHbt2oW1tTW1tbXo6uqio6OD\nh4cHAwMDSKVSrKysCA8P58qVKyJIExERIf6d+Ph4Zs+eTVNTE1lZWQLYUVNTw/jx45GTkyMwMBBn\nZ2cUFBQYHBwU2jOZH9PHxwctLS3MzMxQUVHh4cOHZGZmMmLECKRSKQMDA9y9e5cpU6aIXY5UKqW5\nuVlkEmxsbNDV1RVDxStXrgiOosyU9Pz5c6qrq8nNzS
 UrKwsdHR2Sk5NZsWIFnp6etLe3o6GhwYQJ\nE2hoaEAikdDV1SWMUQEBARw/fpz29nbU1dVpb2/H39+fvr4+/Pz8aGxsZNasWQLvbmpqymeffYaO\njg7btm1j9OjR3L17F19fX2pra4mMjGTnzp08e/aMlpYWYeiWSqUMDg5y5swZxowZg7KyMs7OzsKV\nYWBgwOjRo9HU1CQ5OZng4GBBs66qqhItwba2NlEWevjwITNnzqS8vJz79+/T3d1NZ2cnZmZmODk5\nibBRQ0MDlpaW9PT00NDQALzduhcXF1NYWMj06dO5ePEiHh4ejB8/nuLiYkF0TklJEW6FyZMnU1ZW\nRmFhIZ6enly9elVYomUGMwsLC+zt7VFQUBA/p6amhoKCAkNDQ6iqqvLixQtiY3w4GrcAACAASURB\nVGP57LPPxL1QW1vLtWvXyMjIQF9fn/7+fvbs2YOnpye7d++mpaWFnp4eHj58yJIlS+jt7aWqqoro\n6GgqKysFMObu3bt/a6fwvzTn/73+9/r/z/WfQ3O2sLAgPDwcf39/njx5wvz58zl//jxaWlrk5eXh\n7u6Ov7+/aBQ6Ojpy+PBhvL29SUhIYPbs2VhbWwsJiUwnvmfPHlJTUzl06BCff/45LS0t2NjYiMGk\ng4MDhYWFQjbb19eHk5MTdXV1fPXVV4SGhvLLL7/w+PFjfv31V/bt28cHH3xATEwMaWlpNDY2Ymdn\nJ+LNsplBRkYG/v7+PHr0CF9fX5ydnXn27BmvX79m48aNVFZWkpeXx/Llyzl8+DABAQFMnjyZb775\nhjdv3uDs7ExoaCgqKir89NNPqKmp4eXlxa1bt+jr62POnDnEx8djamoq3BOhoaE0NjYSHx/PnDlz\niI2NpbW1lYKCAj777DNUVVVJTEykq6uLzMxMAgICCAwMJC8vj8LCQgwMDGhoaGDhwoV0dHTw6NEj\n5OTkiI2NJTQ0VLAFZSKV4cOHM
 2rUKJHZd3FxISsri0ePHjFr1iyam5sxMjJi3LhxlJeXc/HiRXR1\nddm0aRP79+8nJCREoMtk5/5jxoxh3759jB49mitXrmBoaIifnx82NjZs3rxZBH+Cg4OJjY1FVVWV\nhIQExo4dS3Z2NoaGhmhoaKCrq4ufnx9ffvklkyZNYvPmzYSHhwvUW3d3N+rq6vT19XH8+HFMTU2Z\nOHGiaFvK/j/2798vkp16enoUFxdjZ2dHWloaeXl5HD16lPPnz3P69GnOnDlDXV0dbW1t1NbWoqCg\nQH9/P/Hx8WKoPHbsWJydnfniiy9ISkrihx9+QE9PT8xEtm/fTnh4OJMmTRImtJMnTzJ79mxKS0sZ\nPnw4ly9fZtasWZiZmXHz5k309fXx8vJi9+7d2NjY4OzsTH9/P/fv38fGxobJkyeTmZnJmjVrBC3q\nf7r+Ea8P+/bt+/b06dOUlpairKxMXV2dIOrEx8ezcOFC6urqxLY5MTERY2NjZsyYgZGREUVFRdTW\n1lJSUkJHRweRkZG8ePECPT09HB0dKSoqYuTIkSJ/XlBQIAZRurq64vjro48+Ql5eHgUFBaqqqrC1\ntSUtLQ1bW1s2bNhARUWFiAxLpVK0tbUZMWIEDQ0NlJeX4+DgwNSpU8nLy+PmzZucOnWK33//HW9v\nb5YuXcqzZ8/o6+sTk3lZYEheXp47d+5gbm6OnZ0dQ0NDGBkZcfHiRYyNjXFzc6OpqYna2losLCyo\nrq7Gx8eH1NRU6urqaG1tRVtbm3v37hEQEMCVK1fYvHkzZWVlzJgxgw8//BBra2txNBYaGkpLSwsv\nX76kr69PzAq0tbWJj49HKpWKrXNvby+NjY1IpVJ6enoEEMbc3FwYr6Kiopg2bZrgRgwfPly87587\ndw5tbW28vLxQUVFh//79dHd3ExcXR3d3N319fVy/fp38/HwSExOxsrJCSUkJIyMj3nnnHfG1enl5\nMTQ0xKZN
 m/j666/FInDr1i3RVcjKyqKzs5M3b97Q0tJCf38/+vr6YqFSV1dny5YtrFmzRgwVg4OD\naW9vJyMjQ3RhJBIJly5dQk5ODi0tLUpLSykoKEBDQ4PGxkasrKyIiYmhuLgYVVVV0QuRlZzu3r3L\n6NGjUVNTIzc3l/Pnz4swWFVVFb6+vrx584bRo0fT1dWFpaUl+/btw83Nja6uLm7fvk1tbS1WVlZo\naGjw7bff0trayokTJ/jss8+4ceMGhw8fFqzH1tZWjIyM8PPz4+XLl1y9epXQ0FCKiooICwvDwcGB\n/fv38+LFi/+cQePQ0JAIpyQnJ2NmZkZrayt5eXkYGRlRWVlJdXU1RUVFPH36lOrqahwdHTl37hwV\nFRUiCNTV1cW8efP44IMPANi4cSNr1qxhYGCAx48fM2XKFEEBlkqlODo6Mjg4yJQpUwgPD+fcuXOC\ns9/S0iKOsdrb28XUG0BOTg4XFxfk5eWpqalhaGgIfX19kpKS2LZtG2ZmZuzatYuPPvqI7777DkVF\nRVauXMnixYtFdn337t309PTg5ORETc1bSXd7e7t4QsmCViUlJQKUUlZWJj6brq4uzMzMxA2Tnp6O\ns7MzRUVFqKmpMX/+fADS09NZtWoV9+7d4+OPP0ZPT0/QnGWDu8DAQAICAliyZAljxoxBXV0dW1tb\nERVWVFQU2ndlZWVWrlxJfX29+Bqtra3JysoiNjaWR48eiZ2VtbU1YWFhSKVSDA0NMTIyYvv27Tg6\nOrJmzRoUFBTo7e3l008/FZ/B8OHDxXu5TAArYzzo6emxdetWtLS06OrqIjw8nG+++UYwKHfv3o2q\nqqqIcvf394vKsAylvnfvXn7++WdKS0vx8fERR4PTp08nOjqa33//nZ6eHmbMmIGtra0Ay+jr6xMU\nFCT6EzNnzgQQ1Ov169ejoKDAnTt3WLduHRYWFpSVldHf38/mzZsxNTWloaFBQHemTZuGl
 pYWurq6\nPHv2jOnTpxMSEiIq2du3bxfDR19fXxYuXMiOHTvEArtv3z7Gjh0rdiZtbW3k5OSwYcMGPvnkEwID\nA1mxYgWPHz8mMjKSdevW/e378R+xKCgqKgrYqexD0dXVxcLCgjt37nDixAn++usv/Pz8aG1tpbW1\nlaysLFRVVdHS0mL79u2MGjWKadOmCUgFvG3Gbd26FYlEQnZ2Nvfu3UNOTo6wsDDMzMxYsmQJg4OD\nLF++XAAtSktLqaio4P3338fb25uBgQHmz5/P119/LZ4EnZ2dvHjxguDgYOLj44mLixMDOmdnZ6RS\nqUB9y4Qyrq6uXLx4kfr6eiH+aGlpwdPTU9B2Vq1aha2tLV5eXmRlZdHa2oqlpSWhoaG4uLjw6aef\noqGhIfh8eXl5AkLj5uZGX18fxsbGODg4sG3bNtrb25GTk6Ovr4+QkBC+//57enp6UFZWZuTIkdy+\nfRslJSVSU1NJTk7m6NGjpKeno6qqiq+vL9euXePLL79kxYoVTJw4EXV1dezt7Tl79ixNTU0Cctrc\n3Cy6KjLGoUyy8/z5c1paWkhKSuLVq1e0tLSQn5/P119/DbzVudXX17N+/XoAcnNziY+P5+TJk7i5\nuVFYWIiPjw8VFRU4ODigq6tLd3c3O3bsoLW1FVNTU/r6+ggMDOS7777DwMCADRs28N1332FoaCiI\nQ/b29sTExKCkpIS6ujqjRo3i4MGDGBsb8+DBA4qKimhqakJBQQFjY2O6u7txc3Pj4cOHhIeHo6mp\nyY0bNwRtS5Y8DAsLQ09Pjy1btnDhwgUKCgqIiIhg7969DA0N8fnnn4tj74KCAqKjo2lvb8fY2JiM\njAzk5OTw8vKivr6eGzdukJWVBcBXX30lHn7vvfceCQkJNDc3s2XLFg4cOICxsbGgS8Hbxb+xsZHk\n5GTq6+vR0NAgMjKSO3fu4O3tLQJ9f+f6R7w+/Pjjj99OmTKFBw8e
 MG/ePAwNDXn+/DlTp07F3d0d\nT09Ppk6dSlZWFh4eHkyePJnm5mYSExNRVFQkKysLR0dHzpw5g7u7O2ZmZvzxxx8MGzaML7/8kkOH\nDhEVFUVBQQF2dnakpqbS19dHZWUlR48eFR6FpqYmvLy86Orq4sqVK/T39/PgwQP8/f0JDQ0lKipK\nsP4nTpxITEwMc+fOFTHS4cOHExgYSFpaGn19fXR2dvL69WuePn2Kj48PXl5eDBs2jISEBHx9fXF1\ndeXYsWOEhYUJFoMMAFtVVcXYsWM5deqU0KLb2tqiq6tLXl4ely9fxs3NjV9++UUUkby8vMjNzWVg\nYEBEa+3s7ARfUfYaIBOdtrW1cfDgQTZt2iSODwcGBpCTk0NFRYX+/n5GjhxJXV0dM2bM4NSpU6JP\n0tbWxueff84ff/wh5LtLliyhuLiYWbNmoa2tja+vrzi+tbW1xdzcnIGBAcrKyggJCRGvLzKM2+HD\nh1m7di2rV68mIiICNzc3YmNjhaRl7ty5yMvLExwcLBbzuLg41NTUBAR23LhxXL9+HXd3d06cOIFE\nIiErKwsHBwdSUlIwMDAQN6GMjTBt2jRiY2MxNjYWpxJDQ0PcunULHx8fCgsLxeI6duxYMjIymDFj\nBr///rsA/ZaVlSEnJ0dpaanwUxw7dgxDQ0Pa2tpITk7G3d0dHx8fcnJykEqlrFmzhnPnzhEfH4+v\nry/x8fFYWlpy9epVdu3ahZycnGB07tixg3379rFmzRqxw5ABXPT09Bg7dqxodqqrq3P8+HG2bt1K\nbGwsTU1NtLW1kZSU9J9TiPr555+/ra6u5oMPPiArKwtFRUX6+vpob2+nqKhIpO48PDw4f/483t7e\npKWl4ePjw8KFC/nzzz+Rl5fH2dmZzs5OdHR0OHbsGAcPHuTRo0fY2dmRmZmJm5sb9+/fp62tjbCw\nMCorKwkODubYsWNoa2vz3nvvcfz4cb766it
 +/vlnHB0dWb58OU+fPkUqlVJfXy8AqHfv3sXLy4v7\n9++joKBAV1cXU6dO5fDhw4LQM336dH744QfMzMxEnLmlpYX09HSMjY05cuQIw4cPp62tTbyXP3/+\nnICAAOrq6qisrCQsLIyhoSEqKytpbW3F19dXyERaW1sF5GP+/PkMDAygpaVFeXk51tbW9PX1ER8f\nT0NDA1OmTGHChAn09PTg7OwsQKehoaEiPZifn8/r169Zvnw5Fy9e5OzZszQ3N/Puu+/y888/Y2Nj\nQ05ODpWVlXh7e3PmzBn8/f0ZP348X375Jc7OzowfP566ujp6e3v58ccf8ff356effkJRUZHm5mZS\nU1NRV1cXFeLa2lpCQkJQUlLi559/ZmBggG3btnHgwAFSUlJEsu/Ro0eCynTkyBFevnzJokWLmDRp\nEnv37qW3t5cRI0bw+vVrkbmQl5fHxsaGmJgYEQk3MDCgqKiIxsZG/P39sbKyIjc3F11dXaysrHBw\ncOD69euYmZlhbm5OXl6eoFPl5eWhrq6OkZERaWlpREVFifCSuro6FhYWzJkzh5qaGhoaGtDQ0GBo\naEjU2mfPnk1VVRUqKiq8evUKd3d36urq+PDDD7l9+zY6OjpUV1eTkJCAl5cXBQUFzJ07l+bmZnJz\ncwkLC2Pr1q3s3buXlJQUxo0bJ+rwJSUlojrf3d1Nd3c3L1++JDg4mHHjxmFnZ8fp06f/78wUJBLJ\ncYlEUi+RSF78Hz+nJ5FIHkkkkqL/+qfu//Frn0skkmKJRFIgkUim/Z1FQUFBgR07dpCUlERhYSGp\nqan09PSgoaFBUFAQ06dPp6enh2fPnrFkyRKePn2KjY0NKioqPHnyhG+//VbkwSUSiVCDXbhwgZcv\nXxIdHY1UKqW4uJjBwUEWLFjAhg0b6OrqwsDAgKNHj4rhko6ODt9++y1+fn6oqqpy+/ZtMjMz8fb2\nZvLkyQC8fv1a+BlXrF
 jBwMAAr1694ubNm7i5uTFq1Cih8frtt98YGhpCW1ubgoICKioqWLlyJba2\ntlhaWmJnZyemwjJwraKiIgYGBgQHB/Pw4UMqKipwdXVl1KhRFBQUYGxszMaNG0lJSUFVVVXcbLLP\ncvXq1SQlJTFv3jwcHR0JDg7m9OnTGBoakpOTI6zYjx8/xtPTk/v377Nnzx6ampqwsLAQOvvZs2cT\nGBjI+vXrmTp1qjgzV1JSor6+HjU1NUHMkvk2uru7aWho4IcffmDt2rX09fWxc+dO5s6dS0dHB56e\nnowaNQp3d3cyMjJoamoiLi6OS5cuAW8HmHPnziUlJYUPPviAxYsXs27dOubNm4e/v7+Yh7x69Yo1\na9YglUqFQ9LW1lb8/cqCOxKJBEAwEerr6zEwMBBYterqampra0UV+vr16wwMDFBfX099fT2amppc\nuXKFS5cu4eTkRHNzM4cPHxZYQCsrK6ysrLh69Sr29vbcvHkTExMTtLW18fT0RCKRMH/+fIaGhti5\nc6dQw7m4uPDJJ5/Q1tbGlStXmDVrFrW1tQI24+npiby8PCdOnBDNWU1NTVEOk1G/jIyMUFRUFPOx\njIwMGhsbCQgIECdZJSUl/61f8z9df2emcBKY/v/6ua1A9NDQkAMQ/V8/RiKRuACLANf/+m9+l0gk\n8v/TH6CsrIySkhIJCQl4enoSFBRES0uLgKZs2LCB7u5uVq5cKXj8enp6gqLb29tLc3OzoD3LCL53\n795l4sSJTJ06lQcPHvw/7L1nWJXnurZ7Dnob9F6kSZGmFEF6U8GK3WlJbNFEY8qMK2ZmzhRNTFw6\nkxgT06wYYy9BsYMiRZqAgID0joBI73XsH87x7Lm+79h7ZX/7z5zHsZ5fw+E4pPi+z/vc931d54WH\nhwcxMTEcOHCADRs2MGXKFM6cOSNOHUZGRsyfP59NmzYhkUjEf66zszMNDQ3U1tYCiOMuwMcff4yq\nq
 iqrVq1i6dKlmJmZkZSURHZ2Nrt27eLMmTMEBwfj7OxMT08PMpmMwsJCWltbRdah3Kuho6PD8PAw\nt27doquri++++47AwECcnJwEr1EqlVJYWCg2oUePHhEQEMD4+LjAp2dmZgqYi5eXF0FBQRw8eJD6\n+npUVVUxNDSkoaGB2bNnCxvuggULmD9/PrNmzeLgwYMAjI2NsX79eiQSCY2NjTQ1NTF9+nTU1NSI\niIhg/fr1VFZWAi+x9729vSQlJVFcXIyvry/nz5+nsrKSs2fPUl9fT0BAAGNjY8TGxuLv7094eDgW\nFhaMjIwIonVQUBCRkZGipj558iRFRUWiyRsfH4+TkxOOjo6Ul5fT29vLpEmTmDZtmiA1p6enI5FI\nWLdunegDyR2G9vb2QuGqpaXF1KlTWbZsmbB/a2trk5qaSkVFBW5ubigpKeHj4yNOBEpKSuzatYuf\nfvoJQCQxffTRRyQkJGBlZcW5c+eIjY2lsrKS+fPnk5OTI/w369atY3BwECMjIzZu3EhtbS07duxg\n06ZNvP766zg4OAAvAbZ6enp4e3uzd+9eSkpKKC0tRU1NjUmTJjE+Pi6YG/IyyN7eHnNzcxQVFUlP\nT2fz5s0cOnRIlM5/dP23m4JMJksBOv6Xt2OAk/94fRJY9E/vn5PJZMMymawGqAR8/7uv0dPTw+PH\nj+np6WF8fJzm5mZ0dXUF5mvVqlW8+uqrpKenY25ujpeXFyEhIURGRgplopqamohVkzcb9+3bR0lJ\nibgIk5KS0NLS4tixY+Tk5HDmzBlmzZrF5s2b6evrIyMjg/b2dnGU7OnpITMzk46ODhITE0XO48TE\nBIsWLSIhIQEXFxfU1dW5desWr732GgUFBbz33nvU1NRQXV3N0qVLUVdXp7GxUdT0RkZGvHjxAldX\nVzGCg5dPM7liTr5ROTo6YmRkxOrVq5k+fboICZV7/vft20deXh4jIyMkJiYKxN
 eGDRvo6Ojg2bNn\nfPXVVyLT0NramsLCQl555RWcnJyE3FnuriwpKeHDDz9EUVGR0NBQdu3axcaNG8nOzhbwl6lTp5Kd\nnc2jR4+wtrYmMTGRrKws/uM//gM/Pz+srKxYtmyZUFgGBQWhp6fHzz//zPXr19HV1SU9PV0Y2GQy\nGRMTE8BLOnJ6ejqJiYlCd3D16lVmz57N0NAQNjY29PT0CA6nnZ0dmzdvpr6+noiICO7evUtgYKD4\neXp7e4GXLA55ienu7i70GnJqc35+Po8ePSIjIwNvb2+cnZ1JSEhgdHQUHR0d8bNLpVIqKipQU1MD\nEFoWec7p8ePHWbJkCV5eXoSGhnL69GkxIkxNTeXLL7/kxo0beHt7M2/ePBwcHDh+/DiRkZFcuHBB\nyKfr6uowNjYW7AstLS00NDTw9fVl+/btIvQmKyuL3Nxcent7qaur49KlSxQUFKCgoMDhw4dpbGxk\n1apVfP311//dbSjW/+n0wUQmkzX/43ULYPKP1xZAwz99rvEf7/2/ruHhYSIjI9m4caOgycybN4+8\nvDwRfZWVlUVcXBw3b94kPT2d5ORkcfxUU1Nj7dq1SKVS7t+/z+nTpwEoKCjAzMyMdevWYWNjg729\nPd988w1nz55lypQphISEiHn/7du3eeuttzh06BD79+8XcVx79+4VQa9yzp2LiwtdXV3Y2tqSnJws\nzE+bN29m/vz5IqympKSE999/n4yMDAoKCigvL0dVVVXYdJ2dndHT08PNzU18v76+vnzyySesWrWK\nsrIyXrx4wYULF0hLSxPcx8LCQp49eyY4EHIEuLa2NkpKSixfvpzDhw+TmJhITU0NAQEBbNmyBQMD\nA+zt7UXTra+vD2NjY+bMmcPw8DANDQ0i+szV1RVbW1tR49vY2PDaa68xadIkMa+fMWMGFRUVhIaG\noqqqytGjR6muriY1NZUffvgBqVSKpaUlly9fprW1FTc3N
 yYmJpg9ezYDAwOkpaWJRl5QUBAAcXFx\n/OlPf6K4uJijR4+iq6tLS0sLT58+xcDAgP7+fsLDwwkICBBy9Fu3buHr68v4+Dh79uyhvr4ea2tr\nYRYDuHDhAtHR0VRVVfHs2TMyMzNZsGABBw4cwMDAAGdnZyGbnzt3LsHBwUyaNImZM2cK9J+ZmRm2\ntrYMDg6KoJ1jx44hk8mYMWMGNjY2/Pjjj+J6LCkpwdvbG3t7e5KTkwkNDWXnzp2sX7+ekydPkpCQ\ngLGxMampqZibmwvtB8CmTZvo7+/nq6++YsOGDSQkJHDt2jXKysrYu3cvzc3NXLhwQcjOlZWV6e3t\nZdasWXh4ePDtt9/S1NREZGQkJ06cIDr6fz3s/z+v/98jSdlLnfT/Z5myRCLZIpFIciQSSc74+Dgp\nKSlMnjwZExMTtLW1uXDhAs7OzqipqbFixQrMzMyYP38+XV1duLu7s2fPHlRVVfnkk0/461//KkCc\nn3zyCZaWlsDLcZf8xj979qzwJTx8+JDx8XEWLlyIg4MD06ZNIzg4GCUlJfH0PHPmDK2trVRWVuLh\n4cG8efOYN28e8NLqfeHCBZFklJOTg6+vL/39/fz00080NzczNDQk+hM7d+5EX18fXV1durq6MDc3\nR1VVldLSUg4cOCDGWwYGBrS0tFBQUEB9fb0wcE2ePFk0jsLDw4mMjERJSYkLFy4QFBSEn58f3d3d\nuLi48OzZM4qLixkbG2PNmjVs3ryZR48e8cMPP3Dq1Cny8/PJzs7mvffeo7m5mf7+fjIzM7lz5w7b\ntm2jvb2dw4cPC1emqqoqnp6eVFdX8+DBA+7fv09CQgJdXV309PTg4uJCYWEh06ZNIzAwkNu3bwsm\nY2VlJa2trejp6VFQUICLiwvh4eECoqupqSk2RzlkxcHBgYcPHwqsnI+PD2vWrOHZs2cMDQ1hbW1N\nQ0MDZ86cYcmSJaxcuRIHBwdmzpyJ
 t7c3w8PD+Pn50dzczNatW0XATkdHB9nZ2SJVW0FBAX19faRS\nKaWlpRw6dAhHR0cyMjJITEwkLi4Od3d34uPjSUpKwsnJifLycrq6uhgbG0NbWxt4aY5TUVERCsJz\n584xNDTE7t27kclkaGtrMzY2xqRJk8jMzGRoaEiEHP1znsWGDRuwsrIS8QQXL14UOLa0tDQOHTqE\njo4OKioqnDt3jpGREfbs2cPZs2eZN2+esIi3tbVRVFREZmYmtbW13L59Gy8vr/8ST/jfrf/TTaFV\nIpGY/ePmNgOe/+P9JsDqnz5n+Y/3/rclk8kOy2QyH5lM5mNmZkZxcTGdnZ0oKiri6emJsrIy5eXl\n9Pf3I5FISEhIoLGxkZqaGhwdHXn99dfx8PDg6NGj2Nvbk5eXx/j4uBANwcvkqZMnT6KoqMjatWtp\nampi+fLlrF69msbGRhISEvj++++5dOkSnZ2drFmzBjMzM1auXIlUKqWvr4/y8nLBI5Dn/CkoKBAY\nGIiOjg6amppoaWlRV1dHW1ubgIvI2YPnz5+noqJCzOIVFBR4/vy5iJ0LCAgQs2k5V1FOWlZXV8fG\nxoYXL17g4+ODr68vjx8/5syZMxgaGrJp0ybBJti0aRN9fX2YmJiIjMV9+/bR2tqKtrY2n376KTY2\nNpiamqKoqChqb3d3d+Bljsbw8DBWVlZoaGhQXV1NZmYmixYt4sMPP8TAwAA1NTWUlZVRUVFBW1ub\n0dFRnjx5wowZM5gyZYpIpPbz8yMwMJCOjg66u7uJjIxkfHyclpYWurq6KC8vp6amhuLiYrq6uoiO\njmbVqlUAIuZPngJ+7NgxZsyYwejoKK2trfzyyy/CDVheXk5eXp4ok+SY86tXr1JbW0tzczP5+fkA\nTJ8+ndbWVkZHRwkNDcXCwgKpVMorr7wiiNt1dXVoaGigoKAgKEbGxsZERUXh6OiItbU1M2bM+C9I\nerl92cTEhEO
 HDuHr60tTUxNWVlakpaXx9ttvi+Tyd955h7KyMlHG+Pv78/nnn+Pi4kJVVRWDg4NC\nV2Fpacn06dMJDQ1FTU2Nv/zlL5SUlNDS0kJYWBg6OjrU1dXh7u6Og4MDhYWF7NixA3t7e1atWsWT\nJ08ICAhg9+7dNDQ08PHHH//hm/v/dFO4Bqz7x+t1wNV/ev9PEolEVSKR2AIOQPYf+QcXL15MT08P\ndXV1PH/+XIhc5FBPCwsLWltbCQsL48aNG9TV1WFrayti43t6ejAwMMDIyIiqqirgpSW7u7ubnJwc\njIyMaG5uJjAwkMuXL6Ovr4+/vz+dnZ1cuXIFJSUlzp07h4KCAoqKiiIcNS4uTlwc8maYnZ0dZmZm\nhIaGoqioyMjICCEhIcydO5eamhq8vLwoKCggKSmJhQsXConu3/72NxYuXMjUqVM5cuQIwcHB9Pb2\n0t3dDcDTp08pKCjA1NQUS0tL9PT0OHz4MDU1NYIsXFxcTEREBFpaWmzatAlPT0+uXLnChx9+iIOD\nA7Nnz2blypW4urqybt06Tp06RU9PDxs2bCA6OhoVFRX09PQoLS3Fz8+P/Px8nJyc0NTUpLq6mrNn\nz9Lb24uysrJIYnr27BkLFiygtbUVVVVV/P398fX15ddff2XFihWoq6uTbw5XtgAAIABJREFUn5/P\nrVu38Pb2FuBbiUTC8+fP0dPTQ1tbm5GREaZPny7k4q2trSxYsEDkdwA8evSI4eFhNm7ciIuLC1FR\nUeIpHB0dzezZs9m3bx/vvvsuqqqqQrFYWFhIZGSk6E2Mj4/j7e2No6Mj8LJB6ejoyOrVq6murubu\n3bs8fPiQnJwcTE1NKS4u5tGjR+jr67Nq1SrRuJ46dSqGhoYUFRXR1tZGXV0d/f39qKurA4imnoaG\nBo6OjiI1zM7OjsWLFxMWFkZubq4QQZ07dw4jIyOcnJzIy8vj5s2bQg7t5OREYmKiuCfKy8sp
 KytD\nR0dHQGfl11xiYiLffPMNx48fJyMjg7CwMNauXcvkyZM5d+4ceXl5hIeHk5iYyMyZM5k1a9Yfvrn/\nyEjyLJABOEkkkkaJRLIJ+E9glkQiqQBm/uPPyGSyYuACUALcBt6UyWTj/93X6Ozs5PHjx6Snp6Os\nrEx6ejoNDQ2Ympoyd+5cvvzyS/r7+5kyZQqFhYUYGxvz3nvvcenSJTEblqcmDw8Pi7osIyODdevW\nkZqayoMHD/Dx8SE6OpoFCxbg7OxMbm4uc+fOxdHRkdHRUfz9/YWFdu3atSQnJxMUFPS/NWkyMzMp\nLCwU2K/h4WEuX75MVVUVUVFRNDU18ezZMyIjIxkeHubgwYM4OztjaGhIc3MzKSkppKamEh8fj7Ky\nshhDzZ07l+7ubgYHB2lra8PQ0FCAZE+cOMGTJ0+YNWsWNTU12NnZERgYyIMHDzh9+jTNzc309vYK\n621zczPXr19neHiY7OxszM3NOXXqlOAC1NTUoKqqytKlS8nPz2d8fBxVVVVee+01QkJCePHiBSoq\nKrx48YLS0lIePnxIbm4uCxYsoK6ujuHhYQICAlBWVubAgQOcPHmSjRs3CkrW+++/j4uLC8ePHxfR\n8XKfSWRkJAsWLCA0NJSioiJ0dXWFbVn+u5BrE1pbW1FTU6OiogJTU1MmJiYICwvj448/prKykvb2\ndn755RdCQkJE3OCjR49QU1Pj5MmTgiOwfv16YmNjBcfSwsKC8vJyzMzMRKiu/JQUFxeHkZERExMT\n5OXlCcp4VFQU2dnZrF+/HiMjIwCioqL461//yvbt28Voedq0aSKGICoqCm9vb1auXMkrr7xCdHQ0\n165d48mTJ4ITqqqqSktLC+fOnRNN546ODiH97unpYd++fcTExODi4iJ8FmvWrGHHjh309fWJNPY/\n//nPREdHY29vj6WlJZMmTSIlJUUkYP+R9UemD6tkMpmZTCZTlslkljK
 Z7JhMJmuXyWSRMpnMQSaT\nzZTJZB3/9PkvZDKZvUwmc5LJZLf+yDfR1dVFWVkZEomEyMhIrl69yqxZs0SYxqZNm7h48SJKSkpM\nnjyZ/Px8SkpK2LhxI3/729+4d+8epaWlNDY2UldXJ2p0f39/nj9/zvr16xkZGWF4eFjQiOUpwCUl\nJairq6OoqMjo6CjDw8Ns27aN7u5uFi9ejKmpKcbGxjx69Iji4mLg5dFu27ZtItlnxowZaGhoiCnK\nvHnzMDc3x8bGhvr6ejQ0NMjMzBT0nzlz5oiocXl+AbxsNFpYWKCpqUleXh5NTU0sXryY/Px8oWA7\ne/YsGRkZzJkzRzjnTp48SUBAAObm5hgaGorjaXh4OBERERgYGODm5oaKigojIyNERUURHR3Npk2b\nuHv3Lq+88gpGRkbo6+uLv9+yZQuzZs0SJxljY2O6urqoqqqisrKSI0eO8ODBA6qqqoiOjmbevHkc\nOXKEzs5OfHx8SE9Pp7a2ll27drFkyRLKy8vJysriyJEj3L59m4GBAWQyGUNDQxgaGvLVV18BUFxc\nLFSrrq6uBAUFYWZmxp/+9Ceh9TcxMWHq1KnIZDLy8vLQ19fn/PnzKCgosGzZMo4dO0ZISAhmZmYi\nIerSpUsilcrKyorBwUEWLlwo/BKurq4sWrRIxAKMjo7S1taGnp4ePT09fPbZZwQEBGBsbMyxY8fE\ng0euXt29ezelpaVcvHiRI0eO8NVXXwnBmVQqpaCgQFCfxsbGyM/PZ8eOHaipqXHt2jUBUfnLX/4C\nIIjg8hs8JSWF3NxcDh06hLu7O/PmzaOsrAxHR0f09fVFWK8cMCsnhssfcOfOnfsjtyLwL6Jo/Prr\nr3fJk4j19PRwcnISKcHykZ+ysjJTp05FTU0NNzc3FBQUxBFYV1eXqKgotLS0cHR0xNvbm8OHDzN/\n/nyuX7+Ou7s7x44dY2xsjM7OTrS1tRkYGEBJSY
 mHDx8SGBhIcXExr732GhKJRIyx7ty5IyzHS5cu\npaGhgfT0dNzc3DAyMhJhtmNjY2zatImioiK0tbUJDw8nLy+PgYEBVFRUCA8PZ2hoSEhn1dTUMDY2\nFlSorKwsioqKcHFxwdzcHGNjYxQUFCguLiY0NBQzMzO6u7sF99/BwUEkCxsaGhIUFCTEOEeOHBEZ\nFMHBwWRmZmJra8vly5cxNDTE3t5eXOxvvvkmjo6OjI+Pk5WVhaqqqiAmJSYmcu/ePSZPnoyHhwcS\niYTVq1eTnp5OZGQkVlZWrFixQkBUFRUV+Y//+A8aGhrESUdbW5u+vj7Ri6ioqBAjShMTE3HUfv78\nOREREYIwpK2tLXJBe3p6hPCssrKSffv2cfjwYRwcHAS4dc6cOTQ2NrJkyRLy8/PJyckhIyMDMzMz\ncnNzuX37NkeOHGF0dBQPDw+SkpIwMDBAU1MTFRUVEeb67NkzsrOzUVNTIzc3lzlz5uDt7c358+c5\ncuQINTU1Is35888/p7e3lxkzZgi8vkwmE7/P6OhoLCwsSEtLE4BWeT9lzZo12Nra8ujRI4FZa2pq\nwsvLi5qaGi5evIi7uzuOjo6UlJRQWVmJlZUVzc3NqKurU1hYSF9fnzjBLV68mIyMDJ49eyYYoc3N\nzXR2djI6OkphYSHbt28nNjb238clKYdXurm58eLFC4KDgwkICKC/v5/k5GS+/PJLXFxcqKmpwdLS\nklu3bvH48WMsLCxQUFCgv79f0Jzd3NxEAtOjR494++230dbWFsKlnJwcIiIiUFFRISsrC3Nzc8rK\nyjA2NiYpKQljY2PCw8Opr6+nu7tbWKhlMhk7duwAXiZPLVy4kODgYDw9PZkyZQo///wz/v7+TJ8+\nndOnT2NoaMiuXbtQUVHhm2++4dGjR/T19ZGXl4e2tjZZWVkiu0LeGV69erVIGmpqamLKlCmcO3eO\nK1euIJFIePDgAT///DNSq
 ZT09HQRKgMIL8ikSZNITU1FTU1NKBanTJnCwoULBQlqYmKCoaEhamtr\nCQoKIiEhgb6+Pu7evUtjYyPR0dFYW1sTHh7O06dPycrKYmBggNOnTyORSDA0NGRwcJALFy4we/Zs\nenp6mDVrFr///jt9fX0MDQ3h4uLC8PAw7u7utLe309bWxqpVqwgKCmLGjBkUFRVRXl4uEqrkUNyr\nV6/S09NDc3Mz06ZNQ0VFBbkEfu/evQJl9vDhQ/7yl78IIpeBgQFHjx4lNzeXSZMmsX79ejIzM0Xj\nrry8XMz6R0ZGUFVVJTU1lZiYGLy8vMTYU47ru3r1KtbW1hQVFSGVSgXNq66ujsrKSt555x3gpSjK\nxsYGFxcXfH19CQsLw9PTk7y8PJSVlXFwcGDfvn1MmjRJiPHkzdKioiLq6urYvHkzjo6OfPHFF0yf\nPh14mcT+7Nkzrl27xvj4OBKJhPnz53Ps2DECAwNF81O+URsZGWFra4uzszM2NjZ4e3tTX1+Pj48P\nenp6oh/2R9a/xKYACJBIV1cXn332GYcOHcLMzIxvvvkGS0tLzp49S1paGnv37sXNzQ1HR0e2bt1K\neHg4LS0tfP311ygqKpKcnCxY/+Pj4xw9epTvv/+eP//5z3z99decPXuW9vZ2Dh48iEwmw9bWFolE\ngq2tLQoKCjx8+JDq6moCAwN55ZVX6OzsZO7cueTl5Qn89uPHj3nw4AHHjx9naGiI4eFhfH19sbe3\nJyEhgdLSUgEIuXPnDrNmzcLV1ZWcnBz+9re/0dDQQEREBO+++67YpODljW1qakpRURE2NjZkZWXh\n4+ODtbU1urq6KCoq8tFHH3Hv3j1MTU2F0CsgIACApUuX4u3tzdKlSzl9+jSKioqkpKSgpKRERkYG\na9asob29naSkJOEylfcW5LmScp29PLhVX1+frKwsQYieMWMGiYmJpKWlsWLFCnbs2CF6A0pKSkIR\nKBf7
 AEgkEqHJcHBwoLi4mPr6enEaHB8fF1Hply9fxtLSkgcPHjB37lyOHDnC5s2b2bdvH/Hx8Rw/\nfpynT58SExPDtWvXkEqlIih28eLF+Pr60tLSwoULF4iNjRW5oo2NjRgYGDA4OIixsTEaGhpMmTKF\ny5cv09/fT1paGmFhYejp6WFgYMCxY8fYvXs3dXV1+Pn5cffuXRwcHFi7di3Nzc3COu3n58fw8DDJ\nycm0trZy+/ZtUlNTcXZ2Fvh8+fXV0NCAn58f5ubmWFlZYWlpyY8//sj+/ftpaWnBzs5ORB76+voy\nOjrKjRs3iIqKYmhoiPz8fKZOncr4+DhPnz6ls7OT8vJy+vr6BMIwPT2dsrIyHjx4IHoinZ2dIp7g\nj6x/ifLh5MmTu+rr6/Hy8gJehrhoaWmJ2DQ57EJDQ4OnT5/y2muvUV1dTXBwMLGxsaxbt44ZM2aQ\nmZkp6te4uDg8PDzo7u4WYJKgoCASExPF2CwiIoKoqCh++uknbG1tuXfvHl5eXjQ1NTF37lx+//13\nYYppa2vj0qVLVFdXs3jxYhQUFPj+++959913GR0dpbOzU0wsurq66OvrY968eaKB1tHRQWhoKLGx\nsSxatAh3d3cuX77M2NgY6urq4njv5eWFuro6T58+JSQkBKlUSldXFwMDAygoKFBUVMSbb77JzZs3\nUVJSwtHRUdSsMTEx4rNubm7cuXOH77//nsOHDyOTybhx4wbj4+N4eXmhp6fHmTNnqKuro6WlhdbW\nVoyNjfH09KShoYGCggKePHlCQ0MDRUVFGBkZiamLubk5mzdv5rvvvkNDQ4OVK1eKQBwPDw+h5JRb\neQMDA6moqEAqlfLo0SNxxAbw9vZmdHSUpqYmbty4IdSGqqqqjI6Osn37diwtLYWj8p95m+bm5iQn\nJzM4OCgAp25ubnR2dvLFF1/Q29vLggULiI2NZcaMGSKV6/r165SVlWFra8srr7yCq
 qoqqqqqjI2N\n8ezZM8zMzIiLi8PJyUn4PeQl3a1bt4iJiaG7u5tTp06xdetWjI2NUVdXx8PDg97eXjw9PcW06v79\n++jr66OiooKBgQEBAQEsW7aMkpISEhMT+eqrrxgfHxf8kOrqakEINzY2prm5GQcHBxQVFfnkk0/Y\nuXMnycnJSKVS7O3tRVTh+fPnCQ0NZdmyZaSnpzNr1iysra3FeNXd3Z3jx4//+7gk//73v+/69NNP\n0dDQ4MiRI+zZs0fw++fOncvt27cxMjJiZGSE4OBgGhsbBRJs1apV/Pbbb+jp6REbG4uLiwvPnz/n\nxo0b+Pv7ExUVhbGxMbW1tYyMjKCvr89XX31FcXExH330EZcuXWLlypXExcVhZmZGdHQ0+fn5TJ48\nGTMzM/Ly8sST3d7eXvgpkpKSRCPu119/paWlRQhS5FZfAwMDIe6JiYmhoKAAqVRKSUkJUqmUlpYW\nysvLsbGxERhuV1dXkpKSUFBQYOHChWzfvh1XV1cmT54sUrM/+OAD4QXQ09NjfHwcGxsbFi5ciI6O\nDl5eXuTn5zNnzhzgJYhUW1sbNTU1hoaGUFZWFuYxV1dXXFxcUFFREfh7+fF6bGwMNzc3qqqq0NbW\nxtbWlu7ubtra2qipqWHLli309/eLC1cmk2FmZoa/v7/ISpRKpeTl5Qm6sZubG729vQL53tzcjIaG\nBhYWFpw6dYqoqChCQ0M5d+4c7e3tQiRkb29Pc3MzM2fO5N69e0RHR/Pw4UNUVVWJj4+nr68PdXV1\n3N3d8fX1xdbWliVLllBWVkZcXByffPIJ5eXlDA8Po6uri76+PsbGxgwMDHDy5EnBZ5CPxOXUI3V1\nddTU1MjLy2PlypV4enpy/PhxWlpaRPDMmjVruH//Pj4+PqSlpfHixQs8PDw4duwYZmZmrFq1it7e\nXtLS0qisrBRTJS0tLVRVVXn27Blqamr09PQwd+5cbt68SVVV
 lVChyglTX375JVOnTqWkpEQ4Na2s\nrBgeHmbdunVUV1fz66+/snXrVu7cuYOTkxPXr18XfbGMjIx/r01BVVUVfX198dTo6uoSgpHq6mpx\nwwAiqNPLy4vz588jk8k4ePAgx44dIysri19++YUXL14I8MqBAwewtrbGzs6O69evs3v3bhYvXszD\nhw/Jysri8uXLJCQkEBYWRnV1tRCV6Ovrs23bNrKyspg5cybd3d3ExcXx+eefU15ejru7u8jxmzx5\nMvb29vj4+KCuro6bmxtJSUm8ePECQ0NDQXXu6upifHyc3t5e1NTU0NDQwMfHhxMnTjBnzhza29tF\nHZ6fn4+WlhYKCgoi88De3l4Qiy0sLFBWVqapqQlDQ0OsrKwICAjgxIkTAMycOZPDhw8LSXJsbCwx\nMTHU1tairKyMqamp0H5YWFgwf/58amtrSUtLw9raGplMRnx8vHga9vf3i7DYvr4+Pv30U7FZV1RU\nEBYWRmNjIx0dHRQVFREaGsrjx48ZHBwULMekpCTMzc2JjY1l8uTJKCsrMzExITIOFixYwLVr13jt\ntdf4+uuvsbS0pLm5GX19ffLy8tDR0aGiooIVK1YglUpRVlZm0qRJuLq60t/fT2VlJVeuXBHeCjne\nTCqVIpFI0NfXR0FBQWR1tre34+zszEcffYS+vj6BgYFigiMvn1JSUkQz9/79+2zYsIGBgQHi4+NZ\nv349Hh4eIuS4qakJU1NTPvroI1avXo2rqytHjx7F0NAQPT09KioqqK6uJicnh/v37xMaGsqxY8fY\nuHGjcMHeu3ePt956S6RaFRYWsmHDBgoLC8nNzWX69OlcvXqVLVu2kJCQgJeXl1BQynmXlpaWgilp\nYGBATk4OT548+R+a8/+s/1n/s/7L+vehOdvb2/PLL7+Qn59Pd3c3c+bMobi4WOQZ9vX1CYDm06dP\nWbhwoQCEvPHGG8yaNYva2lokEglVVVV
 4eXnh5eXFe++9h5OTE76+vhw8eBAnJycBpTA0NCQ/P5/3\n3nuPn376SWQx6uvr09nZSWlpKba2tsyaNYs7d+5w+fJl/Pz8OHz4sAikOXfuHGvXrkVBQYGWlhZk\nMhlWVlbo6+tjZGREcnIy5eXltLS0sGPHDlH29Pb20traikwm48CBA2RkZODv78/MmTOZNGkSr7/+\nOvv27SMiIgInJye++OIL3n33XQoLCxkZGUEikdDZ2SnISmlpaUyePBktLS3U1NQYHx9HUVFR9Eds\nbW1JTU0VmQFyTJyKigoZGRksWbKEDz74QHgzTExMmJiYwNraGnNzczo7O4mLiyM0NBRzc3Nmz57N\n+Pg46enp9PX1ER4ezsmTJ2lubhaW9IsXL2JgYCByHWpqakTwzunTp5kzZw4jIyMMDAzg7e1Nc3Mz\nO3bs4NVXX0VPTw9zc3M++OAD3nnnHXR0dIiOjqakpISbN2+KzIvAwEBBSR4aGiI+Pp6//vWvbN26\nleXLl5OTk4NMJuPcuXN88803bNu2jbi4OGJjYwkLC8PLy4uqqirs7e2FazU9PZ2RkRFhKU9KSmLu\n3LnIZDKcnJy4du0apqamqKioEBMTw5IlS3jttdfw8PAgNTUVLS0t8vPzKS4uZseOHWhpaVFeXk5D\nQwNdXV1cv36dmTNnEhAQQFxcHBs3biQ9PV30ee7cucPOnTtJSUlBW1ubXbt2YWdnJxrQVlZW+Pn5\n0draip2dHaqqqiL0Nzg4mPXr13P69GmKi4uRSCTU1tYyMDAgCOF/ZP1LTB8GBweFmktXV5fffvsN\nZWVlNm7cyKRJk7C1tcXS0lK4/Pr7++ns7OS7775DXV2d3t5e4dmXSCRs27YNgFdeeYW+vj5xwQ0N\nDTF79mycnZ1pbGzE3d2drVu3EhQURGBgoIg6k8+rly5dyrJly4iOjmbnzp28+uqrAAIFr6ioSGtr\nK83NzSQlJdHY2E
 hBQQGJiYl8+umn6Onpoaenx/Lly2lqakJbW5uUlJT/MiL68ssvSUhIAF4qOwMC\nAoiPj2fKlCmoqKhw5coV/Pz8UFFREUnMK1asoL+/H6lUip+fH4aGhqirqzN9+nTy8vKYM2cOt2/f\nprGxUVjA/fz88PLyIiYmBl1dXVJSUnj48CEVFRXk5uaKsufNN99k2rRphIeHo6+vT0dHhxh/LVmy\nRABWPv/8c6RSKUFBQQwODrJjxw7S09NJSUnhxIkT1NfXU1RUxHvvvYeOjg4uLi5IpVKSk5Nxc3Mj\nNDSUrq4uXFxcuH37Nunp6cBLQ4+ysjImJibs3r0bS0tLrKysePjwITU1Nejq6pKYmEhTUxNXr17l\n6NGjDAwMUFpaipOTEw0NDezZs0dshnKLs9w0JKcpx8XFkZOTg7q6Ojk5OdjY2JCdnY2DgwOurq5c\nunQJJSUlent7hXiorKxMNFrlcuSwsDA0NTVpamrCyMhIOGHnz59Pfn4+Z86cwdLSktLSUnp7e1m4\ncCESiQQNDQ1sbGwoLi5GS0sLKysrkU4GL0vkq1ev8tlnn4kJz6uvvsqCBQswMDCgp6eH58+fU1VV\nhYODA6Ojo/T09LBgwQLu3r1LRUUF169fFxEDe/bs+cP347/EpiCRSJg6darQBISFhREWFkZtbS0d\nHR1kZWURERGBlZUVU6dOxcDAgOLiYtTV1YXSTs7Gz8rKEuaPiYkJTE1N+fjjj+nq6sLCwoLCwkKG\nh4cZGRnB0dGRpqYmJiYm6OjoYNmyZXh6eqKrq8vRo0fp6+vjz3/+M83NzTQ2NgrJ7OPHjwX05fHj\nx/j5+bFmzRoiIyNZuXIlMpmMN954AzU1NWQymRgvymGk8gBTV1dXgoODBRtAWVkZLS0tBgcHxVM/\nNDQUZ2dnfvjhB27cuCEaY/b29jg6OpKbmyti0Zuampg8eTLFxcXo6Ojg5OTEnTt38PT0JDk5mfP
 n\nz3PgwAGmTZuGjo4Oa9euJTQ0lPz8fIKCghgeHiY2NlZMKtra2jAwMOCHH37A0tKStLQ0RkZGqK2t\n5dVXXxUNyW+//Zbjx49z6tQpPD09RZ0+NjaGs7MziYmJDA0NCWy5m5sbV65cEapSU1NT9u7dC7yE\n1qipqdHY2Mj777/P5cuXyc7OxtbWVljBDxw4wMKFC1m8eDG7du0S8fb+/v40NDTwySef0NbWhr29\nPfb29gC8/fbbqKqqUl9fz7vvvsvRo0fR09MjNTWVtrY2MZHIzs4mNTWVNWvWCCBwamoq3t7ewvna\n1dWFn58f8HJSlpqaSlVVFWVlZVhbW9Pe3o6xsTEpKSl4e3vzww8/4Ovri52dHbW1tZiYmJCQkEB9\nfT0FBQUUFxeLzVmucNXU1BSKz2+++YaWlhbOnj0rRpNKSkrCpdre3k5qaiqlpaW8/fbb1NXVUVBQ\ngL29PRMTE+jp6fHll1/+4fvxX2JTGB8fJzY2FmNjY0HNLS4uRldXl/7+fvr7+/n666/FmCgnJ4cX\nL17w22+/kZqayr1790SG4fDwMHFxccBLi7OLiwvLly8nMTGRyMhIVq9ejampKS0tLcJUVFdXR0JC\nAosWLRIef2VlZYqKioiJieHkyZNoaGjw888/A+Dl5cXp06eZmJhAKpWioqLCjz/+KPIi/vSnP1FY\nWEhPTw+WlpaC+iRX6xkZGdHa2kpKSgpPnz4VHfbly5dz7tw5pFIpNTU1REZGYmhoSElJCYsWLWLh\nwoUcPXoUDQ0NIdhJTExkZGREjMGUlZUZGRnhs88+IzY2ljfffJPs7Gx0dHSEVbizsxNzc3NmzJgh\nTDynT59mcHAQT09P6uvrWbRoEcbGxjx9+pR169Yxc+ZM9PX16enpwd/fn19//RVfX18OHz6MjY2N\n8IPIG3/yBqOpqSlTp07Fz8+PiooKZDKZ2Fhyc3MBKCsro76+HnhJy6qqqu
 LMmTNERESwfft2tm7d\nyo0bN+js7ERFRYUbN26wePFiwTK4fPkybm5u2NnZcerUKUHGKigoECPhDRs2kJWVhYuLCzdv3mR4\neJijR4/S1dWFmZkZCgoKuLm5YWNjg6KiIvb29kyePFmAdZ48ecKePXv49ttvOXPmjBBb3b59W6gT\n5fAYIyMjKioqxElx3bp1mJmZoaKiIrIapFIpkZGRTJ06FSsrK+Lj49m4cSNLliwBXlKt5Yi1+vp6\nfv/9d5YvXy5Ccr28vPD396ekpERkV5aUlNDa2sqbb76JoaEhOTk5PHr0iMuXLwuNzR9Z/xLTh2+/\n/XbXl19+iZ2dHUVFRYLYc/fuXczMzICXCi85CDU4OBhlZWWMjIzw9fWlqqoKOzs7xsbGMDQ0xM/P\nj9OnTxMeHo6xsTFOTk5kZWURFhbGkSNHUFNTE+nGDQ0NQheQmZmJpqYmRUVFYpfPzs4mIiKCFy9e\nCIjLW2+9RV9fH2VlZfT29lJZWYm5uTkNDQ3o6uqSk5ODkpIS/f39lJWVCZakjo4OQ0NDODk5icjz\n5cuXixzFLVu2sGLFCgwNDRkbGxMbVHZ2thhNjY2NiTTq5ORk1q1bJwxYZmZmrFmzhqysLGQymUjJ\nGh0dFZJsTU1NLl68KOLX/fz8KCsrExLvsrIyfHx8cHd3Jz09neHhYdzc3Dh27BizZ89mZGSEtLQ0\ngoODkUqleHh4COXh2NgY7e3tJCYmoqCggJeXFzY2NgwPDwMvswzkm+327ds5f/48Xl5eGBgYUFRU\nJNKtgoKC8PDwYM+ePaxZs0YkW7/xxhtMmjSJ+vp6Zs6cydDQEFFRUXR1dYnAYE9PT1paWvj000+5\ncuUK/f39FBcXMzg4KL5HIyMjioqK8PDwoKenh+nTp1NVVSX0ATqLteqtAAAgAElEQVQ6OqSnpwuN\nyPTp0ykvL2fevHlMmjSJoKAgLCwsRLpXZ2cnqqqqT
 J8+XZwoa2tr2bp1Kx0dHdy5c0f0FeSO32nT\npqGkpMSDBw9QVlbG19cXGxsbLC0t+e6775g/fz7V1dVCcr1lyxaqq6s5evQo1tbW3Lp1C6lUyuDg\nIPv37xfl6rNnz8jJyWFsbEz03gYGBpg1axaHDh369xlJ/vjjj7vg/4ZgPn78mIyMDAwMDHjx4gVB\nQUGcPn0aFRUVgRi/c+cOysrKWFhYMDExga6uLhcvXmT9+vU8efKE+Ph4XF1dxZhN7ueXX+zKyso4\nOzvj4+Mjnmpy4ImRkRHLly8nPj6e+fPni1m1oaEh58+f58033yQuLo6oqCjBgHjjjTeoqanBxMSE\njIwMIVhRV1enrq5ONKakUimenp48f/4cExMTvv32W7y8vDh16hRLlizh6tWrFBcX09fXR0REBFu2\nbGHx4sW0trYK7oJEIkFBQYHo6GgRj37p0iWcnJw4ceIEUqmU8vJyUlNTRSnV3NyMgoKCqOkPHTrE\nzp072b59Oz/88INITx4aGhImse+//57g4GCGh4cJCQkRDIHR0VGGhoZoaGgQzVP511yyZAnz58+n\nu7ubnp4ePv/8c2bOnImLiwuBgYHY2Njg4OAgFIZpaWnY2dlhZ2fH77//LiLfTU1N+frrr/Hy8qKx\nsZF3332XU6dOUVlZyapVq/Dy8sLJyYmrV6/S29uLv78/UqmU7OxsLC0t+fnnn9m0aRN6enrcvHmT\nq1evoq+vT2xsLEuXLuXx48dYWlqiqalJY2Mjg4ODJCcnExYWJqC3SUlJrFixAjU1Nfr6+lBSUhLX\nwffff8+TJ0+E6e7jjz/mzp07LFy4kLa2Ntra2rCysuL58+csWLAAMzMzNDQ0RBmkpKTEsWPHWLp0\nKfb29hgbG5OYmEhSUhIZGRmivLKyssLd3Z2EhARUVVUZHh6ms7OTjz76SAQUOzg48OTJEz744AMM\nDAxISUlh3bp1qKiocPnyZTw9
 PRkdHf3D3od/iZGks7OzzM3NjXXr1gm6zOjoKLdv32bVqlV0d3eT\nkZEhCLuWlpYsXryYrKwsent7RYrSqlWrCA4OpqKigpkzZ5Kens79+/eZNGkSKioqQgm3cuVKwR78\n/fffCQkJEdBUeZOvtLSUwMBA4Xx866232LVrFydOnMDPz090cvv6+jA3N0dTUxMFBQXKy8uFOUse\n5yU/PTx8+FBkTG7cuBFNTU0mJiZob28nKCiIJ0+ecP36dZYuXcqPP/5IWFiYaJSlpqYKqbOamhq/\n/PILjo6OhIWFMTY2RkpKCiUlJbz66qsoKiri5uZGR0cHkydP5tKlS2zbto0LFy7Q2NjIlClTaGho\nwMfHB3t7e3777TdCQkL4/fffiYmJQUdHhxMnThASEsLw8DCZmZns2rULBQUFvvrqK0xMTARCbv/+\n/YyNjREWFkZwcDAZGRlIJBL8/PzE5jU6OkpzczMjIyPExMRw7949AXKRyWSsWrWKnJwcVq9ezY4d\nO6iqqiI8PJzc3Fy8vb15+PAh2tramJmZ4ezsTEVFBaWlpSxfvpw7d+6I0khTU5N58+bR2tpKamqq\nCIt58803aW1tJT09HTs7O77//nu2bt0qNtShoSHhg9m1axfLli3Dzs6O7u5uIiIiGB0d5bfffuOd\nd95hYGCAjo4OXFxcsLCw4ODBg4SHh5OWloaWlpYgfH/66adCXdve3k5fXx+pqanY29vj7e2Nvr6+\n4HsMDg4yNDREY2Oj6GMVFRWJaZpcaZuVlSWyJx48eIC7uzs+Pj7cv3+f1tZWnJ2dhQ3d39+frKws\n9PT0RH9qwYIFf2gk+S/RUxgcHGTBggXY2NgglUppamqio6ODzZs3Ex8fz+3bt9HS0uLVV19l0aJF\n9Pf3U15ezvPnz7G3t2f69Ons3r2b7u5urly5Irzura2tIkg1OzubdevWoaury8GDB4WwSB4nJvfU\nv//++2h
 oaLBs2TL09PTw8PCgpaWFkpISQSnavHkzWlpatLS0kJ6ezvj4OJaWloSEhFBbW0t/fz8Z\nGRlMTExQVFREcnIyv/32GzNnziQkJAQTExOqq6u5cOECw8PDwsB1/vx5FBUV2bJlC9nZ2QwNDdHU\n1ERqaiqAKCP6+vrw9vYWISuamposWbKExYsXU1hYSHV1Nc3NzWITXbNmDR0dHWhpaaGpqUl9fT06\nOjpkZmaipKSElpYWDQ0NqKmp/RfvxenTp3n+/DnOzs6iByKXoBcXF9Pb20tUVBSenp7o6ekxMjIi\nsO5VVVUkJSURFxfHhx9+SEREBJWVlXz22Wfk5eUxOjpKbW0tvr6+PH/+XBCtTUxMhE/A2NgYQ0ND\ngoOD0dTUxNXVlaqqKkZHR9HS0mLv3r1Mnz4dqVQqSskTJ04gk8l4+PAhtra2Ij5v//79qKmpkZ6e\nzpIlSzhz5gwtLS0kJiZSX1+PVCrFzs6Os2fPIpVKMTY2RklJiaNHj4oJxDfffENpaSkVFRWCeD1t\n2jTq6uqEIam1tZWKigra2tqIjY3FyckJGxsbIiIieOedd4Q35Oeff+bbb79lbGyMvLw8Ll26xNy5\nc4WBKycnR6DjADHq3rx5sxCpyWX1ckCNnZ0dKioqgkgWHh7Oixcv0NPTE9fYH1n/EuXDL7/8smvS\npEkMDQ1RUVEh7MzyEFBfX1+ePHmCu7s7vb29aGpq0tbWxoIFC0hKSuLcuXNYW1tjZWXFo0ePyM3N\nJTs7mylTplBbW0tVVRVLly5lypQpSKVSNm7ciI6ODq2trYSHh6OoqMjjx48FgVldXZ3Ozk6ysrJw\ncnKisrKSwMBArl27Rn5+Pm+88QY+Pj7o6+sLFkNubi7GxsZs2rSJ+Ph4TE1NsbW1FaYWf39/urq6\nMDQ0FJRiExMTXrx4gZWVFUePHmXt2rWkpaWxceNGLC0t6ejo4K9//StWVlZkZWUxNjaG
 ubk5urq6\normVmJiItra2sNk6ODjg5ubGw4cPGR0dpaysjJ9++onGxkbS0tKIiopi5syZPHv2DAUFBeLj4zEy\nMqK2thYXFxdxjA8KCsLc3Jzr168TFhZGe3u7SM62tbWlsLAQNTU1FBQUsLGx4dq1a5iYmIhQ32PH\njtHZ2SmmGqamply7do233nqLiIgIbt68ibq6OjExMYSEhGBubs6TJ0/45JNPaGpqIiQkRJRFenp6\nuLq6oq6ujouLC9ra2kilUsHylKse5TmSbW1t5OXlYWZmRkNDA/Hx8dy8eVNsEL29vVy5coX8/Hz8\n/PxwcHAgKiqK27dvY2lpiaKiIv7+/ly/fh09PT3U1dXR0tIiICCAR48e0d7eTlNTE0+ePBHjcj8/\nPy5evEh4eDidnZ3CbXv//n0MDQ25f/8+tbW1BAQEMDQ0xMcff4xUKgVebvYxMTEMDQ1RVVVFcnIy\nnp6eqKur09HRwa1btxgZGaGwsJAZM2Zw69YtJiYm+O677/Dw8MDV1RUvLy8GBweprKxEV1eX8fFx\nGhoa0NTUpLi4GE1NTW7evPnvY50eGBgQT2Rra2u2bt0qwkoMDQ15+vQpIyMj4ki+cuVKQkNDuXfv\nHkZGRkRERAiijoODA5qamgAEBweTk5MjNoCWlhZSU1NJTU3F3d2dtWvX8p//+Z+UlZXx+PFjAgMD\nhQvNwsKCjRs3cvLkSaZMmUJ9fT2TJ08GXnIWhoeHSUlJEcKQ6dOno62tTV1dHc3NzZSUlJCZmcme\nPXvEnNjJyYnx8XFycnKYNm0ad+/exdHRkfPnzwMvPQrLly/n73//O2NjY+Tk5LBjxw66u7vx9PQU\nNXllZSUffvghOjo6mJmZUV1dzZ07d4iKimJ0dJQHDx4I6MyqVavYuXMnIyMj7Ny5E4CTJ09SW1uL\ntrY227ZtY3R0lBcvXjA4OMivv/6Knp4ezc3NIiI9PT2dxsZGAfG
 QNwcVFBQEBXnWrFloaGiQm5uL\ng4MDM2bMYNOmTdTX1+Pv709NTQ379u1jcHCQ06dP4+HhwYYNG/j000/ZsWOHIA7JHYa6urpMTEyw\nZMkSESCsr6/PhQsXePDgAaqqqsyePZvdu3fj6uqKt7c3iYmJQsPi4uLC7NmzxSTqyZMnbNy4kRkz\nZqCiooK3tzfe3t60tLSInpGXlxePHz/mxo0b3Lhxg/b2dgFJzc/Px8bGBg0NDfT19QXENyoqCiUl\nJYqKijA0NOTw4cOUlpaKa8HQ0JCOjg5ef/11nJ2dCQoKwsrKips3b9LX18fTp08ZGBjg7t27mJiY\n4Ov7MhFB3jyVB+LExMTw+eefExcXh7m5ORYWFvz2229MnjyZpqYm4uPjMTQ0ZGBggJaWFtavX49U\nKmX//v3Y2tqKackfWf8Sm4KioiLq6upoamqSkZHBjRs3MDIyEhyFGTNmCJPLrVu3ePbsGXv37hUl\nxaxZs9DS0uLkyZMChgoQEBDA9u3befz4MSoqKqK/0NPTw+3bt7l+/bo4gpqbm5Obm0tWVhYjIyP0\n9PSIKC8fHx88PDyEHsDNzY3MzEy0tLSIiIjAw8ODZcuWsX//fhITE9mwYQP29vYcOHCAefPmoaqq\nyjvvvIOqqipXrlxhyZIlnD17lrfffpubN2+K38PZs2fp6upCXV0dXV1d3N3dRZ6gRCIhJCSEgoIC\n3NzcMDU1FSPE0NBQAL744gvKysooKytjypQpDA4OUlNTg42NDR988AE//vgj3d3d+Pr6YmVlxb17\n93Bzc8PZ2ZnPP/8cOzs7MY4LCgqisbERPT093n//fQoLC3n77bdZvXo1AwMDLF++HH19fa5evYqG\nhoZAz1lZWYlcy99//52lS5fS2tqKkZERbW1tjI+PY2xsjKmpKYcPH6asrIyQkBBiYmIAmDNnDi9e\nvCAlJYW8vDz279+PtrY27e3tPHv2TMBR0t
 PTMTQ0JDw8nAMHDtDX14dEIkFdXZ2RkRHBh5DzEQwM\nDHByciIjIwMXFxcCAgIE0EdBQYFDhw6hqamJVCplzpw5aGpqMnPmTI4cOUJSUhLq6up0d3cTGBiI\ni4uL4B4oKCiQlpZGf3+/yCBxc3OjsLCQzMxMgXtLTk7GwcGBY8eOUV1dTX9/P/X19YSGhvLOO++I\nSIOBgQHg/6LuPaOyutq23eOmS++9I10EaYIogoIiwS6xlxg15rHExJpmS2KMJUaNvRs1sXcDqIAg\nIgrSpAnSkY4gSId7/+Bh7ucd+xv7db/f9yN7jeEfgjchWWuuOa/rvI6jj2p9//59tm/fzqtXr7h6\n9SqxsbHY29sTFhaGra2tEBNbW1szevRoUlJSCAwMxN/fn7Nnz/L+/XsWLFggzFYfev0jFgUlJSUc\nHR2FkXnEiBEAYviotraW7OxsDhw4wKpVq4iKimLmzJmcP3+e3377jfT0dIyNjTEyMsLHx4ekpCSg\nT72loaHBypUrxY1cU1MjiNDv37/n+PHjnDp1SvAAhw4dKo4M0IeJ72cR9Nt7/Pz8WLhwIQMHDiQ1\nNRVNTU1++ukn9u/fT3BwMO/evaO1tZWQkBCGDBnC48ePGTVqFI8fP0ZLS4vY2Fg8PDx4+PAhEydO\nFMiwkSNHUl9fz+TJkwW0Vk9Pjzlz5qClpcW5c+cwMDBATU0NNzc3uru7SU9PR1FRkdGjR2NjY0Ng\nYCAjRozA3t6eTz75hObmZsGZ2

<TRUNCATED>


[09/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/bfeb6127
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/bfeb6127
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/bfeb6127

Branch: refs/heads/master
Commit: bfeb61279d8d8af19a65d2c5ca628d65a09269c9
Parents: 8c9b594
Author: Moaz Reyad <mo...@gmail.com>
Authored: Sat Jun 24 15:00:57 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:16:00 2017 +0800

----------------------------------------------------------------------
 CMakeLists.txt                        |   2 +-
 doc/en/docs/notebook/index.ipynb      |  12 +--
 doc/en/docs/notebook/mlp.ipynb        | 103 +++++++++----------
 doc/en/docs/notebook/model.ipynb      | 126 +++++++++--------------
 doc/en/docs/notebook/rbm.ipynb        | 128 +++++++++++------------
 doc/en/docs/notebook/regression.ipynb | 157 +++++++++++++++++++----------
 python/setup.py.in                    |   1 +
 7 files changed, 278 insertions(+), 251 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0522f61..fbd4f9c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -195,7 +195,7 @@ IF(PACKAGE)
 	IF(PYTHON2)
 		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python-dev, libpython2.7, python-pip, python-numpy, python-pillow")
 	ELSE()
-		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python3, python3-dev, python3-pip, python3-numpy, python3-pillow")
+		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python3, python3-dev, python3-pip, python3-numpy, python3-pillow, python3-matplotlib")
 	ENDIF()
 
 	SET(CPACK_GENERATOR "DEB")

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/doc/en/docs/notebook/index.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/index.ipynb b/doc/en/docs/notebook/index.ipynb
index 0c29187..29f689f 100644
--- a/doc/en/docs/notebook/index.ipynb
+++ b/doc/en/docs/notebook/index.ipynb
@@ -22,7 +22,7 @@
     "  * [Multi-layer Perceptron](./mlp.ipynb)\n",
     "* Deep learning models\n",
     "  * [Convolutional Neural Network (CNN)](./cnn.ipynb)\n",
-    "  * [Recurrent Neural Networks (RNN)](./rnn.ipynb) (WIP)\n",
+    "  * [Recurrent Neural Networks (RNN)](./rnn.ipynb)\n",
     "  * [Restricted Boltzmann Machine (RBM)](./rbm.ipynb)\n",
     "* [Distributed training](./distributed.ipynb) (WIP)\n",
     "* [Rafiki](./rafiki.ipynb) (WIP)"
@@ -112,21 +112,21 @@
  "metadata": {
   "anaconda-cloud": {},
   "kernelspec": {
-   "display_name": "Python [conda env:conda]",
+   "display_name": "py3",
    "language": "python",
-   "name": "conda-env-conda-py"
+   "name": "py3"
   },
   "language_info": {
    "codemirror_mode": {
     "name": "ipython",
-    "version": 2
+    "version": 3
    },
    "file_extension": ".py",
    "mimetype": "text/x-python",
    "name": "python",
    "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.13"
+   "pygments_lexer": "ipython3",
+   "version": "3.5.3"
   }
  },
  "nbformat": 4,


[05/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/doc/en/docs/notebook/regression.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/regression.ipynb b/doc/en/docs/notebook/regression.ipynb
index a61aed6..4484564 100755
--- a/doc/en/docs/notebook/regression.ipynb
+++ b/doc/en/docs/notebook/regression.ipynb
@@ -12,11 +12,14 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "metadata": {
-    "collapsed": true
-   },
+   "metadata": {},
    "outputs": [],
    "source": [
+    "from __future__ import division\n",
+    "from __future__ import print_function\n",
+    "from builtins import range\n",
+    "from past.utils import old_div\n",
+    "\n",
     "%matplotlib inline\n",
     "import numpy as np\n",
     "import matplotlib.pyplot as plt"
@@ -33,7 +36,7 @@
    "cell_type": "code",
    "execution_count": 2,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -53,14 +56,12 @@
   {
    "cell_type": "code",
    "execution_count": 3,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "<matplotlib.legend.Legend at 0x7f3c7ebe0050>"
+       "<matplotlib.legend.Legend at 0x7fee42985f60>"
       ]
      },
      "execution_count": 3,
@@ -69,9 +70,9 @@
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEKCAYAAAD9xUlFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8lOW5//HPDQQSwg5hTUJYZQsgBlBwAZcWkIogx3qq\ntZUiarVqWyuL4oqKWhdOq1JcihylHiWAiChuWHBBBcQkhC3sgbBDAiSBJHP9/sg0P0SWAJl5MjPf\n9+s1r8w8c8/MdZPwfOdZ5hpnZoiIiABU8boAERGpPBQKIiJSRqEgIiJlFAoiIlJGoSAiImUUCiIi\nUkahICIiZRQKIiJSRqEgIiJlqnldwOlq1KiRJSUleV2GiEhIWbp06W4zizvVuJALhaSkJJYsWeJ1\nGSIiIcU5t6k847T7SEREyigURESkjEJBRETKhNwxheMpKioiOzubwsJCr0vxXHR0NPHx8URFRXld\nioiEoLAIhezsbGrXrk1SUhLOOa/L8YyZsWfPHrKzs2nVqpXX5YhICAro7iPn3EbnXLpzbrlz7ien\nDLlS/+Ocy3LOpTnnepzJ6xQWFtKwYcOIDgQA5xwNGzbUFpOInLFgbCn0N7PdJ7hvINDOf+kNvOT/\nedoiPRD+Q/8OInI2vD7QPASYZqUWA/Wcc808rklEpFIpKvHx4udZ/LBlf8BfK9ChYMAnzrmlzrlR\nx7m/BbDlqNvZ/mU/4pwb5Zxb4pxbsmvXrgCVGnyLFi2ic+fOdO/enYKCAnJychg8ePBJHzN37lwe\neOCBIFUoIl7L2JrL1S98yVMfruaDjO0Bf71Ah8KFZtad0t1EtzvnLj6TJzGzKWaWYmYpcXGn/JR2\nyHjzzTcZO3Ysy5cvJyYmhmeffZabb775pI+58soree+998jPzw9SlSLihcKiEp76cBVDXviSHXmH\neen6HowZ2CHgrxvQUDCzrf6fO4FZQK9jhmwFEo66H
 e9fFlIeeOABnn/++bLb9913H5MmTTrpY155\n5RXefvttxo8fz/XXXw9AamoqAwYMAOC5555jxIgRAKSnp9OlSxfy8/NxztGvXz/mzp0boNmIiNe+\n27iXQZMW8eLn6xh2bgs+/dMlDEwOzp71gB1ods7FAlXM7ID/+s+AR44ZNge4wzn3FqUHmHPNLOds\nXvfh91aQuS3vbJ7iJzo1r8ODv+h8wvtHjBjBsGHDuPvuu/H5fLz11lt89tlndO/e/bjjp0+fzsiR\nI/niiy8YPHgww4cPZ8OGDdSvX58aNWoAcNddd9GvXz9mzZrFY489xj/+8Q9q1qwJQEpKCosWLeLa\na6+t0HmKiLcOHi7mqQ9XMe3rTbSoF8O0Eb24uH1w944E8uyjJsAs/9kw1YDpZvahc+5WADObDMwD\nBgFZQD5wUwDrCZikpCQaNmzI999/z44dOzj33HNp2bIly5cvL/dz5OTkcPSusSpVqjB16lS6du3K\nLbfcQt++fcvua9y4Mdu2bavQOYiIt/69ZhfjZqazLbeA3/ZJ4i8/P4fYGsH/KFnAXtHM1gPdjrN8\n8lHXDbi9Il/3ZO/oA2nkyJFMnTqV7du3M2LECA4cOMBFF1103LHTp0+nU6dOP1oWExPzk88XrF27\nllq1av0kAAoLC4mJianYCYiIJ/bnH+HRuStJXZZNm7hY3rnlAlKSGnhWT1h8orkyGDp0KA888ABF\nRUVMnz6dqlWrntaWQvv27dm4cWPZ7dzcXO68804WLlzIHXfcwYwZMxg+fDgAa9asoUuXLhU9BREJ\nsnnpOTzwbgb78ou4o39b7ri0LdFRVT2tSaFQQapXr07//v2pV68eVaue/i81NjaWNm3akJWVRdu2\nbfnjH//I7bffTvv27Xn11Vfp378/F198MY0bN2bBggU88cQTAZiFiATDzrxCxr+bwfwVO+jSog6v\nj+hF5+Z1vS4LUChUGJ/Px+LF
 i3nnnXfK/ZipU6f+6PYdd9zB1KlTmTBhAq+99lrZ8oSEBLKysgDY\nsWMHBQUFJCcnV0jdIhI8ZsY7S7OZMDeTw8U+xgzswMgLW1GtqtefI/7/FAoVIDMzk8GDBzN06FDa\ntWt3xs8zdOhQ9uzZc9Ixmzdv5plnnjnj1xARb2zZm8+4WeksWrubXkkNmHhNMq3janld1k8oFCpA\np06dWL9+fYU818iRI096f8+ePSvkdUQkOEp8xrSvN/LUh6up4uDRq7twfa9EqlSpnH3KwiYUzEzN\n4Cj9dxCRyiFr5wHunZHGss376XdOHI8NTaZFvcp95mBYhEJ0dDR79uyJ+PbZ//k+hejoaK9LEYlo\nRSU+Jn++jr99lkXNGlV57pfduLp7i5BYP4VFKMTHx5OdnU04Ncs7U//55jUR8UZ6di5/mfEDq7Yf\nYHDXZjx0VWca1arhdVnlFhahEBUVpW8aExFPFRaV8Nwna3h54Xoa1arBlF+fx886N/W6rNMWFqEg\nIuKlbzfsZXRqGht2H+K6ngmMHdSRujGh+T3pCgURkTN0oLCIJz9cxRuLN5PQIIY3R/amb9tGXpd1\nVhQKIiJnYMGqnYyblc72vEJ+d2Er/vyz9tSsHvqr1NCfgYhIEO09dIRH52Yy6/uttGtci9Tb+tAj\nsb7XZVUYhYKISDmYGXPTcnhozgpyC4q487J23N6/DTWqedvArqIpFERETmFHXiH3z87g48wddI2v\nyxsje9OxWR2vywoIhYKIyAmYGf/33RYem7eSI8U+xg3qwIi+lauBXUVTKIiIHMfmPfmMmZnGV+v2\n0LtVA568pitJjWK9LivgFAoiIkcp8Rn//HIDf/1oNdWqVGHC1V34VSVuYFfRFAoiIn5rdpQ2sFu+\nZT+XdmjMY0O70Kxu5W5gV9EUCiIS8Y4U+3jp83X8fcFaatWoxqTrunNVt+Yh0cCuoikURCSi/bBl\nP6NT01i
 1/QBXdWvOg7/oRMMQamBX0RQKIhKRCo6U8OzHq3n1iw3E1a7BKzemcHmnJl6X5TmFgohE\nnK/W7WbszHQ27cnnv3slMnZQB+pEh2YDu4qmUBCRiJFXWMQT81bxr28307JhTabf3Js+bUK7gV1F\nC3goOOeqAkuArWY2+Jj7+gHvAhv8i2aa2SOBrklEIs8nmTu4f3YGOw8UcvNFrfjTFecQUz28WlRU\nhGBsKdwFrARO9JnwRceGhYhIRdlz8DAPv5fJnB+20aFpbf7x6/PollDP67IqrYCGgnMuHrgSeAz4\nUyBfS0TkaGbGnB+28dCcFRw8XMzdl7fj9/3aUr1a+LaoqAiB3lJ4HrgXqH2SMX2cc2nAVuAeM1tx\n7ADn3ChgFEBiYmIg6hSRMJKTW8D9szL4dNVOuiXU46lrunJO05OthuQ/AhYKzrnBwE4zW+o/dnA8\ny4BEMzvonBsEzAbaHTvIzKYAUwBSUlIsQCWLSIjz+Yy3vtvCE/NWUuTzcf+VHbmpbyuqRkiLiooQ\nyC2FvsBV/pV9NFDHOfeGmd3wnwFmlnfU9XnOuRedc43MbHcA6xKRMLRx9yHGzExj8fq99GnTkInD\nupLYsKbXZYWcgIWCmY0FxkLZWUb3HB0I/uVNgR1mZs65XkAVYE+gahKR8FNc4uO1LzfwzEdrqF61\nChOHJfPLngkR2aKiIgT9cwrOuVsBzGwyMBy4zTlXDBQA15mZdg+JSLms2p7H6Blp/JCdy+UdmzDh\n6i40rRvtdVkhzYXaOjglJcWWLFnidRki4qHDxSW8sGAdLy7Iom5MFA8P6cyVyc20dXASzrmlZpZy\nqnH6RLOIhJRlm/cxekYaa3ceZOi5LRg/uBMNYqt7XVbYUCiISEjIP1LMMx+t4bUvN9C0TjSv/TaF\nSzuogV1FUyiISKX3ZdZuxsxMY8veAm44P5HRAzpQWw3sAkKhICKVVm5BEU/MW8lb322h
 VaNY3hp1\nPue3buh1WWFNoSAildJHK7Zz/+wM9hw6wq2XtOHuy9sRHaUGdoGmUBCRSmXXgcM89N4K3k/LoUPT\n2rz6m54kx9f1uqyIoVAQkUrBzJi9fCsPv5dJ/uES/nxFe27t14aoqmpgF0wKBRHx3Nb9Bdw3K53P\nV++iR2I9nhrelbaN1cDOCwoFEfGMz2e8+e1mJs5bic/ggcGd+E2fJDWw85BCQUQ8sX7XQcakpvPt\nxr1c1K4Rjw9NJqGBGth5TaEgIkFVXOLj5UUbeO6TNURXq8LTw7sy/Lx4taioJBQKIhI0mdvyuDf1\nBzK25vHzzk14dEgXGtdRA7vKRKEgIgFXWFTC3z/LYvK/11GvZnVeur4HA5ObeV2WHIdCQUQCaumm\nvYxOTSdr50Gu6RHP+MEdqVdTDewqK4WCiATEocPFPD1/Na9/vZHmdWN4fUQvLmkf53VZcgoKBRGp\ncIvW7mLszHSy9xXwmwta8pcBHahVQ6ubUKDfkohUmNz8Iia8n8k7S7Np3SiWd269gJ5JDbwuS06D\nQkFEKsSHGdsZ/24Gew8d4ff92nDnZWpgF4oUCiJyVnYeKOShOSuYl76dTs3q8M/f9qRLCzWwC1UK\nBRE5I2ZG6rKtPDo3k4KiEv7y83MYdXFrNbALcQoFETlt2fvyGTcrg4VrdpHSsj4Tr+lK28a1vC5L\nKoBCQUTKzecz/nfxJp78cBUAjwzpzA29W1JFDezChkJBRMola+dBxqSmsWTTPi5q14gnhiUTX18N\n7MJNwEPBOVcVWAJsNbPBx9zngEnAICAf+K2ZLQt0TSJSfkUlPqYsXM+kT9cSE1WVZ/6rG8N6tFAD\nuzAVjC2Fu4CVQJ3j3DcQaOe/9AZe8v8UkUogY2su985IIzMnj4FdmvLwkM40rq0GduEsoKHgnIsH\nrgQeA/50nCFDgGlmZsBi51w951wzM8sJZF0icnKFRSVM+nQtUxa
 up0FsdSbfcB4DujT1uiwJgkBv\nKTwP3Auc6Hv1WgBbjrqd7V+mUBDxyHcb9zJ6Rhrrdx/i2pR47hvUibo1o7wuS4IkYKHgnBsM7DSz\npc65fmf5XKOAUQCJiYkVUJ2IHOvg4WKe+nAV077eRHz9GN74XW8ubNfI67IkyAK5pdAXuMo5NwiI\nBuo4594wsxuOGrMVSDjqdrx/2Y+Y2RRgCkBKSooFrmSRyPTvNbsYNzOdbbkF3NQ3iXt+dg6xamAX\nkQL2WzezscBYAP+Wwj3HBALAHOAO59xblB5gztXxBJHg2XfoCI++n8nMZVtpExfLjFsv4LyWamAX\nyYL+VsA5dyuAmU0G5lF6OmoWpaek3hTsekQikZkxL307D87JYH9+EX+4tC13XNqWGtXUwC7SBSUU\nzOxz4HP/9clHLTfg9mDUICKlduYVMv7dDOav2EFyi7pMG9GbTs2Pd8a4RCLtNBSJEGbGO0uzmTA3\nk8PFPsYM7MDIC1tRTQ3s5CgKBZEIsGVvPmNnpvNF1m56JTVg4jXJtI5TAzv5KYWCSBgr8Rmvf7WR\np+evpmoVx4Sru/CrXolqYCcnpFAQCVNrdxxgdGoayzbvp985cTw+NJnm9WK8LksqOYWCSJgpKvEx\n+fN1/O2zLGJrVOX5X3ZnSPfmamAn5aJQEAkjadn7uXdGGqu2H2Bw12Y8dFVnGtWq4XVZEkIUCiJh\noLCohOc+XsPLi9YTV7sGL9+YwhWdmnhdloQghYJIiFu8fg9jUtPYuCef63omMHZQR+rGqIGdnBmF\ngkiIOlBYxMQPVvHmN5tJaBDD9JG96dNWDezk7CgURELQglU7GTcrne15hYzo24p7ft6emtX131nO\nnv6KRELI3kNHeHRuJrO+30q7xrVIva0PPRLre12WhBGFgkgIMDPmpuXw0JwV5BYUceelbbldDewk\nABQKIpXcjrxC7p+dwceZO+gaX5c3b+5Nh6
 ZqYCeBoVAQqaTMjP/7bguPzVvJkWIf4wZ1YERfNbCT\nwFIoiFRCm/fkM2ZmGl+t20PvVg148pquJDWK9bosiQAKBZFKpMRn/PPLDfz1o9VUq1KFx4cmc13P\nBDWwk6BRKIhUEqu3lzawW75lP5d1aMyEoV1oVlcN7CS4FAoiHjtS7OPFz7N4YUEWtaOjmHRdd67q\npgZ24g2FgoiHfthS2sBu9Y4DDOnenAcGd6KhGtiJhxQKIh4oOFLCsx+v5tUvNtC4djSv/iaFyzqq\ngZ14T6EgEmRfrdvN2JnpbNqTz696JzJmYAfqRKuBnVQOCgWRIMkrLOKJeav417ebadmwJv+6+Xwu\naNPQ67JEfkShIBIEn67cwX2zMth5oJBRF7fmj5e3J6a6WlRI5aNQEAmgPQcP8/B7mcz5YRvnNKnN\nP359Ht0S6nldlsgJBSwUnHPRwEKghv91ZpjZg8eM6Qe8C2zwL5ppZo8EqiaRYDEz5vywjYffy+RA\nYRF/vLw9t/VrQ/VqalEhlVsgtxQOA5ea2UHnXBTwhXPuAzNbfMy4RWY2OIB1iARVTm4B98/K4NNV\nO+mWUI+nh3elfZPaXpclUi6nDAXn3B+AN8xs3+k8sZkZcNB/M8p/sdOuUCRE+HzGW99t4Yl5Kyny\n+bj/yo7c1LcVVdWiQkJIebYUmgDfOeeWAa8B8/0r/FNyzlUFlgJtgRfM7JvjDOvjnEsDtgL3mNmK\n8pUuUnls3H2IMTPTWLx+L33aNGTisK4kNqzpdVkip82VZ/3uSj9v/zPgJiAFeBt41czWletFnKsH\nzAL+YGYZRy2vA/j8u5gGAZPMrN1xHj8KGAWQmJh43qZNm8rzsiIBV1zi47UvN/DMR2uoXq0K91/Z\nkWtTEtSiQiod59xSM0s51bhyHfXybxls91+KgfrADOfcU+V8/H5gATDgmOV5ZnbQf30eEOWc+8k3\nj5vZFDNLMbOUuLi48
 rykSMCtzMlj2Etf8fi8VVzULo5P/nQJv+yZqECQkFaeYwp3ATcCu4FXgL+Y\nWZFzrgqwFrj3BI+LA4rMbL9zLga4AnjymDFNgR1mZs65XpSG1J6zmZBIoB0uLuGFz7J48fN11I2J\n4u+/Opcrk5spDCQslOeYQgNgmJn9aJ+Nmfmccyc7a6gZ8Lr/uEIV4G0zm+ucu9X/+MnAcOA251wx\nUABcV97jFSJeWLZ5H6NnpLF250GGntuCBwZ3on5sda/LEqkw5TqmUJmkpKTYkiVLvC5DIkz+kWL+\nOn8N//xqA83qRPPYsGT6n9PY67JEyq28xxT0iWaRU/hi7W7GzEwje18BN5yfyOgBHaitBnYSphQK\nIieQW1DEY+9n8vaSbFo1iuX/Rp1P79ZqYCfhTaEgchzzV2xn/OwMdh88zC0Xt+aPV7QnOkoN7CT8\nKRREjrL74GEenLOC99Ny6NC0Nq/8JoWu8WpgJ5FDoSBCaQO7Wd9v5ZG5meQfLuHPV7Tn1n5tiKqq\nBnYSWRQKEvG27i/gvlnpfL56Fz0S6/HU8K60bawGdhKZFAoSsXw+481vNjHxg1X4DB78RSduvCBJ\nDewkoikUJCKt33WQManpfLtxLxe1a8TjQ5NJaKAGdiIKBYkoxSU+Xl60gec+WUN0tSo8Nbwr/3Ve\nvFpUiPgpFCRirNiWy+jUNDK25jGgc1MeubozjWtHe12WSKWiUJCwV1hUwt8+W8vkf6+nfs3qvHR9\nDwYmN/O6LJFKSaEgYW3ppr3cOyONdbsOcU2PeMYP7ki9mmpgJ3IiCgUJS4cOF/P0/NW8/vVGmteN\n4fURvbikvb6LQ+RUFAoSdhau2cXYmelsyy3gxvNb8pcBHahVQ3/qIuWh/ykSNvbnH2HC+yuZsTSb\n1nGxvHPLBaQkNfC6LJGQolCQsPBhRg73z17Bvvwj/L5fG+68rJ0a2ImcAYWChLSdBwp58N0VfJCx\n
 nc7N6zD1pp50aVHX67JEQpZCQUKSmTFjaTYT3l9JQVEJowd0YORFrdTATuQsKRQk5GzZm8+4Weks\nWrublJb1eXJ4V9rE1fK6LJGwoFCQkOHzGf+7eBNPfrgKBzwypDM39G5JFTWwE6kwCgUJCVk7DzIm\nNY0lm/ZxSfs4Hhvahfj6amAnUtEUClKpFZX4mLJwPZM+WUvNGlV59tpuDD23hRrYiQSIQkEqrYyt\nudw7I43MnDwGJTfl4au6EFe7htdliYQ1hYJUOoVFJUz6dC1TFq6nQWx1Jt9wHgO6NPW6LJGIELBQ\ncM5FAwuBGv7XmWFmDx4zxgGTgEFAPvBbM1sWqJqk8vtu415Gz0hj/e5D/DIlgXGDOlK3ZpTXZYlE\njEBuKRwGLjWzg865KOAL59wHZrb4qDEDgXb+S2/gJf9PiTAHDxfz1IermPb1JuLrx/DG73pzYbtG\nXpclEnECFgpmZsBB/80o/8WOGTYEmOYfu9g5V88518zMcgJVl1Q+C1bv5L6Z6eTkFXJT3yTu+dk5\nxKqBnYgnAvo/zzlXFVgKtAVeMLNvjhnSAthy1O1s/zKFQgTYd+gIj87NZOb3W2kTF8uMWy/gvJZq\nYCfipYCGgpmVAN2dc/WAWc65LmaWcbrP45wbBYwCSExMrOAqJdjMjHnp23lwTgb784u4o39b/nBZ\nW2pUUwM7Ea8FZRvdzPY75xYAA4CjQ2ErkHDU7Xj/smMfPwWYApCSknLsLigJITvzChn/bgbzV+wg\nuUVdpo3oTafmdbwuS0T8Ann2URxQ5A+EGOAK4Mljhs0B7nDOvUXpAeZcHU8IT2bGO0uyefT9TI4U\n+xg7sAO/u7AV1dTATqRSCeSWQjPgdf9xhSrA22Y21zl3K4CZTQbmUXo6ahalp6TeFMB6xCNb9uYz\ndmY6X2TtplerBkwclkxrNbATqZQCefZRGnDucZZPPuq6AbcHqgbxVonPeP2rj
 Tw9fzVVHDx6dReu\n75WoBnYilZjO+5OAWLvjAKNT01i2eT/9zonj8aHJNK8X43VZInIKCgWpUEUlPiZ/vo6/fZZFbI2q\nPP/L7gzp3lwN7ERChEJBKkxa9n7unZHGqu0H+EW35jz4i040qqUGdiKhRKEgZ62wqITnPl7Dy4vW\n06hWDV6+MYUrOjXxuiwROQMKBTkri9fvYezMdDbsPsR/90pgzMCO1I1RAzuRUKVQkDNyoLCIiR+s\n4s1vNpPYoCbTR/amT1s1sBMJdQoFOW0LVu1k3Kx0duQVMvLCVvzpZ+2pWV1/SiLhQP+Tpdz2HjrC\nI++tYPbybbRvUosXr+/DuYn1vS5LRCqQQkFOycyYm5bDQ3NWkFdYxF2XteP2/m2pXk0tKkTCjUJB\nTmp7biH3z87gk5U76BZflyeH96ZDUzWwEwlXCgU5LjPjre+28Pj7Kyny+bhvUEdGXNiKqmpRIRLW\nFAryE5v2HGJMajpfr9/D+a0bMHFYV5IaxXpdlogEgUJBypT4jH9+uYG/frSaqCpVeHxoMtf1TFAD\nO5EIolAQAFZvP8C9qWn8sGU/l3VozIShXWhWVw3sRCKNQiHCHSn28eLnWbywIIva0VH8z3+fyy+6\nNlMDO5EIpVCIYMu37Gf0jDRW7zjAVf4Gdg3VwE4koikUIlDBkRKe+Wg1r325gca1o3n1Nylc1lEN\n7EREoRBxvlq3mzGp6Wzem8+veicyZmAH6kSrgZ2IlFIoRIi8wiKemLeSf327haSGNfnXzedzQZuG\nXpclIpWMQiECfJK5g/tmp7PrwGFuubg1d1/enpjqVb0uS0QqIYVCGNtz8DAPvZfJez9so0PT2kz5\ndQrdEup5XZaIVGIKhTBkZry7fBsPv7eCg4eL+ePl7bmtXxs1sBORU1IohJlt+wu4f3YGn63aSfeE\nejw1vCvtm9T2uiwRCREKhTDh8xnTv93MxA9WUeIzxg/u
 xG/7JKmBnYicloCFgnMuAZgGNAEMmGJm\nk44Z0w94F9jgXzTTzB4JVE3hasPuQ4xJTeObDXvp27YhTwztSmLDml6XJSIhKJBbCsXAn81smXOu\nNrDUOfexmWUeM26RmQ0OYB1hq7jEx6tfbODZj9dQvVoVnrwmmWtTEtSiQkTOWMBCwcxygBz/9QPO\nuZVAC+DYUJAzsDInj9GpaaRl53JFpyZMuLoLTepEe12WiIS4oBxTcM4lAecC3xzn7j7OuTRgK3CP\nma0IRk2h6nBxCS98lsWLn6+jXs0oXvhVDwYlN9XWgYhUiICHgnOuFpAK3G1mecfcvQxINLODzrlB\nwGyg3XGeYxQwCiAxMTHAFVdeSzftY3RqGlk7DzKsRwvGX9mJ+rHVvS5LRMKIM7PAPblzUcBcYL6Z\nPVuO8RuBFDPbfaIxKSkptmTJkoorMgTkHynm6fmrmfrVRprVieaxYcn0P6ex12WJSAhxzi01s5RT\njQvk2UcOeBVYeaJAcM41BXaYmTnnegFVgD2BqikUfbF2N2NnpbFlbwE3XtCSewd0oFYNnUksIoER\nyLVLX+DXQLpzbrl/2TggEcDMJgPDgducc8VAAXCdBXLTJYTkFhTx2PuZvL0km1aNYnn7lgvo1aqB\n12WJSJgL5NlHXwAnPfppZn8H/h6oGkLV/BXbGT87gz2HjnBbvzbcdVk7oqPUwE5EAk/7ISqRXQcO\n89CcFbyfnkPHZnV49Tc9SY6v63VZIhJBFAqVgJkx6/utPDI3k/zDJfzl5+cw6uLWRFVVAzsRCS6F\ngse27i9g3Mx0/r1mF+e1rM+T13SlbeNaXpclIhFKoeARn89445tNPPnBKgx46BeduPGCJKqogZ2I\neEih4IF1uw4yJjWN7zbu46J2jXh8aDIJDdTATkS8p1AIouISHy8v2sBzn6whuloVnh7eleHnxatF\nhYhUGgqFIFmxLZfRqWlkbM1jQOe
 mPHJ1ZxrXVgM7EalcFAoBVlhUwt8/y2Lyv9dRr2Z1Xrq+BwOT\nm3ldlojIcSkUAmjJxr2MTk1j3a5DXNMjnvGDO1KvphrYiUjlpVAIgEOHSxvYvf71RprXjWHaiF5c\n3D7O67JERE5JoVDBFq7ZxdiZ6WzLLeDG80sb2MWqgZ2IhAitrSrI/vwjTHh/JTOWZtM6LpZ3brmA\nlCQ1sBOR0KJQqAAfpOcw/t0V7Ms/wu392/CHS9XATkRCk0LhLOw8UMiD767gg4ztdG5eh9dH9KRz\nczWwE5HQpVA4A2bGjKXZTHh/JQVFamAnIuFDoXCatuzNZ9ysdBat3U3PpPpMvKYrbeLUwE5EwoNC\noZx8PmOwHbfqAAAHD0lEQVTa1xt5av5qHPDokM5c37ulGtiJSFhRKJRD1s4DjE5NZ+mmfVzSPo7H\nhyXTol6M12WJiFQ4hcJJFJX4mLJwPZM+WUtM9ao8e203hp7bQg3sRCRsKRROIGNrLvfOSCMzJ48r\nk5vx0FWdiatdw+uyREQCSqFwjMKiEiZ9upYpC9fTILY6k284jwFdmnpdlohIUCgUjvLthr2MSU1j\n/e5D/DIlgXGDOlK3ZpTXZYmIBI1CATh4uJgnP1jF/y7eRHz9GN74XW8ubNfI67JERIIu4kNhweqd\n3DcznZy8Qkb0bcU9P29PzeoR/88iIhEqYGs/51wCMA1oAhgwxcwmHTPGAZOAQUA+8FszWxaomo62\n79ARHp2byczvt9KucS1m3NqH81rWD8ZLi4hUWoF8S1wM/NnMljnnagNLnXMfm1nmUWMGAu38l97A\nS/6fAWNmvJ+ew4PvriC3oIg7L23L7Ze2pUY1NbATEQlYKJhZDpDjv37AObcSaAEcHQpDgGlmZsBi\n51w951wz/2Mr3I68QsbPzuCjzB0kt6jLGyN707FZnUC8lIhISArKznPnXBJwLvDNMXe1ALYcdTvb\nv6zCQ2HBqp
 3c+db3HCn2MXZgB353YSuqqYGdiMiPBDwUnHO1gFTgbjPLO8PnGAWMAkhMTDyjOlo1\niqVHYn0euqozrRrFntFziIiEu4C+VXbORVEaCG+a2czjDNkKJBx1O96/7EfMbIqZpZhZSlzcmX3X\ncVKjWF4f0UuBICJyEgELBf+ZRa8CK83s2RMMmwPc6EqdD+QG6niCiIicWiB3H/UFfg2kO+eW+5eN\nAxIBzGwyMI/S01GzKD0l9aYA1iMiIqcQyLOPvgBO2k7Uf9bR7YGqQURETo9OvxERkTIKBRERKaNQ\nEBGRMgoFEREpo1AQEZEyrvQEoNDhnNsFbDrDhzcCdldgOaFAc44MmnNkOJs5tzSzU376N+RC4Ww4\n55aYWYrXdQST5hwZNOfIEIw5a/eRiIiUUSiIiEiZSAuFKV4X4AHNOTJozpEh4HOOqGMKIiJycpG2\npSAiIicRlqHgnBvgnFvtnMtyzo05zv3OOfc//vvTnHM9vKizIpVjztf755runPvKOdfNizor0qnm\nfNS4ns65Yufc8GDWFwjlmbNzrp9zbrlzboVz7t/BrrGileNvu65z7j3n3A/+OYd0t2Xn3GvOuZ3O\nuYwT3B/Y9ZeZhdUFqAqsA1oD1YEfgE7HjBkEfEBpF9fzgW+8rjsIc+4D1PdfHxgJcz5q3GeUtmkf\n7nXdQfg916P0e9AT/bcbe113EOY8DnjSfz0O2AtU97r2s5jzxUAPIOME9wd0/RWOWwq9gCwzW29m\nR4C3gCHHjBkCTLNSi4F6zrlmwS60Ap1yzmb2lZnt899cTOm33IWy8vyeAf5A6bf/7QxmcQFSnjn/\nCphpZpsBzCzU512eORtQ2//FXrUoDYXi4JZZccxsIaVzOJGArr/CMRRaAFuOup3tX3a6Y0LJ6c7n\nd5S+0whlp5yzc64FMBR4KYh1BVJ5fs/tgfrOuc+dc0udczcGrbrAKM+c/w50BLYB6cBdZuY
 LTnme\nCOj6K5DfvCaVkHOuP6WhcKHXtQTB88BoM/OVvomMCNWA84DLgBjga+fcYjNb421ZAfVzYDlwKdAG\n+Ng5t8jM8rwtKzSFYyhsBRKOuh3vX3a6Y0JJuebjnOsKvAIMNLM9QaotUMoz5xTgLX8gNAIGOeeK\nzWx2cEqscOWZczawx8wOAYeccwuBbkCohkJ55nwTMNFKd7hnOec2AB2Ab4NTYtAFdP0VjruPvgPa\nOedaOeeqA9cBc44ZMwe40X8U/3wg18xygl1oBTrlnJ1zicBM4Ndh8q7xlHM2s1ZmlmRmScAM4Pch\nHAhQvr/td4ELnXPVnHM1gd7AyiDXWZHKM+fNlG4Z4ZxrApwDrA9qlcEV0PVX2G0pmFmxc+4OYD6l\nZy68ZmYrnHO3+u+fTOmZKIOALCCf0ncaIaucc34AaAi86H/nXGwh3EysnHMOK+WZs5mtdM59CKQB\nPuAVMzvuqY2hoJy/50eBqc65dErPyBltZiHbPdU59y+gH9DIOZcNPAhEQXDWX/pEs4iIlAnH3Uci\nInKGFAoiIlJGoSAiImUUCiIiUkahICIiZRQKIiJSRqEgIiJlFAoiZ8n/fQ1pzrlo51ysv6d/F6/r\nEjkT+vCaSAVwzk0AoiltQpdtZk94XJLIGVEoiFQAf1+e74BCoI+ZlXhcksgZ0e4jkYrRkNIveKlN\n6RaDSEjSloJIBXDOzaH0W8FaAc3M7A6PSxI5I2HXJVUk2PzfblZkZtOdc1WBr5xzl5rZZ17XJnK6\ntKUgIiJldExBRETKKBRERKSMQkFERMooFEREpIxCQUREyigURESkjEJBRETKKBRERKTM/wMY2i8P\nOiX0cgAAAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYUAAAEKCAYAAAD9xUlFAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xd4lGX69vHvHVpC6BB6QqjSgggBVCxgW0QWBFl1V9eC\niLq6lt1ViqKoWNBV19/aFsVVVllXCShiwQIsWFDBkoTQQg+EFiCUFJLM9f6R2byIlAAz82Qm5+c4\ncmTmmXvmue5MMmeeMtc4M0NERAQgyusCRESk4lAoiIhIGYWCiIiUUSiIiEgZhYKIiJRRKIiISBmF\ngoiIlFEoiIhIGYWCiIiUqep1AcerUaNGlpiY6HUZIiJhZcmSJTvMLO5Y48IuFBITE1m8eLHXZYiI\nhBXn3PryjNPuIxERKaNQEBGRMgoFEREpE3bHFA6nqKiIrKwsCgoKvC7Fc9HR0bRs2ZJq1ap5XYqI\nhKGICIWsrCxq165NYmIizjmvy/GMmZGTk0NWVhatW7f2uhwRCUNB3X3knFvnnEtzzv3onPvFKUOu\n1P855zKdc6nOuR4nsp6CggIaNmxYqQMBwDlHw4YNtcUkIicsFFsK/c1sxxFuuxho7//qA7zo/37c\nKnsg/I9+DiJyMrw+0DwEmGqlFgH1nHPNPK5JRKRCKSrx8cL8TH7auDvo6wp2KBjwiXNuiXNu1GFu\nbwFsPOh6ln/ZzzjnRjnnFjvnFm/fvj1IpYbewoUL6dKlC927dyc/P5/s7GwGDRp01PvMnj2b+++/\nP0QViojX0jflcunzX/LExyv4KH1L0NcX7FA4y8x6ULqb6Fbn3Dkn8iBmNtnMks0sOS7umO/SDhtv\nvvkmY8eO5ccffyQmJoann36aG2+88aj3ueSSS3j//ffJy8sLUZUi4oWCohKe+Hg5Q57/kq17Cnnx\nqh6Mubhj0Ncb1FAws03+79uAmUDvQ4ZsAuIPut7Sv
 yys3H///fztb38ru37vvffy7LPPHvU+r7zy\nCm+//Tbjx4/nqquuAiAlJYUBAwYA8MwzzzBixAgA0tLS6Nq1K3l5eTjn6NevH7Nnzw7SbETEa9+t\n28nAZxfywvzVDDutBZ//6VwuTgrNnvWgHWh2zsUCUWa213/5IuChQ4bNAm5zzr1F6QHmXDPLPpn1\nPvj+UjI27zmZh/iFzs3r8MCvuxzx9hEjRjBs2DDuvPNOfD4fb731FnPnzqV79+6HHT9t2jRGjhzJ\nF198waBBgxg+fDhr166lfv361KhRA4A77riDfv36MXPmTB555BH+8Y9/ULNmTQCSk5NZuHAhl19+\neUDnKSLe2ldYzBMfL2fq1+tpUS+GqSN6c06H0O4dCebZR02Amf6zYaoC08zsY+fczQBm9hLwITAQ\nyATygOuDWE/QJCYm0rBhQ3744Qe2bt3KaaedRqtWrfjxxx/L/RjZ2dkcvGssKiqK1157jW7dunHT\nTTfRt2/fstsaN27M5s2bAzoHEfHWf1duZ9yMNDbn5nPdmYnc/atTiK0R+reSBW2NZrYGOPUwy186\n6LIBtwZyvUf7jz6YRo4cyWuvvcaWLVsYMWIEe/fu5eyzzz7s2GnTptG5c+efLYuJifnF+wtWrVpF\nrVq1fhEABQUFxMTEBHYCIuKJ3XkHeHj2MlK+z6JtXCzv3HQGyYkNPKsnIt7RXBEMHTqU+++/n6Ki\nIqZNm0aVKlWOa0uhQ4cOrFu3rux6bm4ut99+OwsWLOC2225j+vTpDB8+HICVK1fStWvXQE9BRELs\nw7Rs7n8vnV15RdzWvx23ndeO6GpVPK1JoRAg1atXp3///tSrV48qVY7/SY2NjaVt27ZkZmbSrl07\n7rrrLm699VY6dOjAlClT6N+/P+eccw6NGzdm3rx5PPbYY0GYhYiEwrY9BYx/L505S7fStUUdXh/R\nmy7N63pdFqBQCBifz8eiRYt4
 5513yn2f11577WfXb7vtNl577TUmTpzIq6++WrY8Pj6ezMxMALZu\n3Up+fj5JSUkBqVtEQsfMeGdJFhNnZ1BY7GPMxR0ZeVZrqlbx+n3E/59CIQAyMjIYNGgQQ4cOpX37\n9if8OEOHDiUnJ+eoYzZs2MBTTz11wusQEW9s3JnHuJlpLFy1g96JDXj8siTaxNXyuqxfUCgEQOfO\nnVmzZk1AHmvkyJFHvb1Xr14BWY+IhEaJz5j69Tqe+HgFUQ4evrQrV/VOICqqYvYpi5hQMDM1g6P0\n5yAiFUPmtr3cMz2V7zfspt8pcTwyNIkW9Sr2mYMREQrR0dHk5ORU+vbZ//s8hejoaK9LEanUikp8\nvDR/NX+fm0nNGlV45opTubR7i7B4fYqIUGjZsiVZWVlEUrO8E/W/T14TEW+kZeVy9/SfWL5lL4O6\nNWPC4C40qlXD67LKLSJCoVq1avqkMRHxVEFRCc98tpKXF6yhUa0aTP59Ty7q0tTrso5bRISCiIiX\nvl27k9EpqazdsZ8re8UzdmAn6saE5+ekKxRERE7Q3oIiJn28nDcWbSC+QQxvjuxD33aNvC7rpCgU\nREROwLzl2xg3M40tewq44azW/PmiDtSsHv4vqeE/AxGRENq5/wAPz85g5g+baN+4Fim3nEmPhPpe\nlxUwCgURkXIwM2anZjNh1lJy84u4/fz23Nq/LTWqetvALtAUCiIix7B1TwH3vZvOpxlb6dayLm+M\n7EOnZnW8LisoFAoiIkdgZvznu4088uEyDhT7GDewIyP6VqwGdoGmUBAROYwNOXmMmZHKV6tz6NO6\nAZMu60Zio1ivywo6hYKIyEFKfMY/v1zLXz9ZQdWoKCZe2pXfVeAGdoGmUBAR8Vu5tbSB3Y8bd3Ne\nx8Y8MrQrzepW7AZ2gaZQEJFK70Cxjxfnr+a5eauoVaMqz17ZncGnNg+LBnaBplAQkUrtp427GZ2S\nyvItexl
 8anMe+HVnGoZRA7tAUyiISKWUf6CEpz9dwZQv1hJXuwavXJPMBZ2beF2W5xQKIlLpfLV6\nB2NnpLE+J4/f9k5g7MCO1IkOzwZ2gaZQEJFKY09BEY99uJx/f7uBVg1rMu3GPpzZNrwb2AVa0EPB\nOVcFWAxsMrNBh9x2HfAksMm/6DkzeyXYNYlI5fNZxlbuezedbXsLuPHs1vzpwlOIqR5ZLSoCIRRb\nCncAy4AjvSf8P2Z2WwjqEJFKKGdfIQ++n8GsnzbTsWlt/vH7npwaX8/rsiqsoIaCc64lcAnwCPCn\nYK5LRORgZsasnzYzYdZS9hUWc+cF7flDv3ZUrxq5LSoCIdhbCn8D7gFqH2XMZc65c4CVwF1mtvHQ\nAc65UcAogISEhGDUKSIRJDs3n/tmpvP58m2cGl+PJy7rxilNj/YyJP8TtMh0zg0CtpnZkqMMex9I\nNLNuwKfA64cbZGaTzSzZzJLj4uKCUK2IRAKfz5j2zQYuenoBX67ewX2XdGLGLWcqEI5DMLcU+gKD\nnXMDgWigjnPuDTO7+n8DzCznoPGvAE8EsR4RiWDrduxnzIxUFq3ZyZltG/L4sG4kNKzpdVlhJ2ih\nYGZjgbEAzrl+wF8ODgT/8mZmlu2/OpjSA9IiIuVWXOLj1S/X8tQnK6leJYrHhyVxRa/4StmiIhBC\n/j4F59xDwGIzmwXc7pwbDBQDO4HrQl2PiISv5Vv2MHp6Kj9l5XJBpyZMvLQrTetGe11WWHNm5nUN\nxyU5OdkWL17sdRki4qHC4hKen7eaF+ZlUjemGg8O6cIlSc20dXAUzrklZpZ8rHF6R7OIhJXvN+xi\n9PRUVm3bx9DTWjB+UGcaxFb3uqyIoVAQkbCQd6CYpz5ZyatfrqVpnWhevS6Z8zqqgV2gKRREpML7\nMnMHY2aksnFnPlefnsDoAR2prQZ2QaFQEJEKKze/iMc+XMZb322kdaNY3hp1Oqe3aeh1
 WRFNoSAi\nFdInS7dw37vp5Ow/wM3ntuXOC9oTXU0N7IJNoSAiFcr2vYVMeH8pH6Rm07FpbaZc24uklnW9LqvS\nUCiISIVgZrz74yYefD+DvMIS/nxhB27u15ZqVdTALpQUCiLiuU2787l3ZhrzV2ynR0I9nhjejXaN\n1a/ICwoFEfGMz2e8+e0GHv9wGT6D+wd15tozE6kSpTeheUWhICKeWLN9H2NS0vh23U7Obt+IR4cm\nEd9ADey8plAQkZAqLvHx8sK1PPPZSqKrRvHk8G4M79lSLSoqCIWCiIRMxuY93JPyE+mb9vCrLk14\neEhXGtdRA7uKRKEgIkFXUFTCc3Mzeem/q6lXszovXtWDi5OaeV2WHIZCQUSCasn6nYxOSSNz2z4u\n69GS8YM6Ua+mGthVVAoFEQmK/YXFPDlnBa9/vY7mdWN4fURvzu2gj9Ot6BQKIhJwC1dtZ+yMNLJ2\n5XPtGa24e0BHatXQy0040LMkIgGTm1fExA8yeGdJFm0axfLOzWfQK7GB12XJcVAoiEhAfJy+hfHv\npbNz/wH+0K8tt5+vBnbhSKEgIidl294CJsxayodpW+jcrA7/vK4XXVuogV24UiiIyAkxM1K+38TD\nszPILyrh7l+dwqhz2qiBXZhTKIjIccvalce4meksWLmd5Fb1efyybrRrXMvrsiQAFAoiUm4+n/Gv\nReuZ9PFyAB4a0oWr+7QiSg3sIoZCQUTKJXPbPsakpLJ4/S7Obt+Ix4Yl0bK+GthFmqCHgnOuCrAY\n2GRmgw65rQYwFegJ5ABXmNm6YNckIuVXVOJj8oI1PPv5KmKqVeGp35zKsB4t1MAuQoViS+EOYBlQ\n5zC33QDsMrN2zrkrgUnAFSGoSUTKIX1TLvdMTyUjew8Xd23Kg0O60Li2GthFsqCGgnOuJXAJ8Ajw\np8MMGQJM8F+eDjznnHNmZsGsS0SOrqCohGc/X8XkBWtoEFudl67
 uyYCuTb0uS0Ig2FsKfwPuAY70\nuXotgI0AZlbsnMsFGgI7glyXiBzBd+t2Mnp6Kmt27Ofy5JbcO7AzdWtW87osCZGghYJzbhCwzcyW\nOOf6neRjjQJGASQkJASgOhE51L7CYp74eDlTv15Py/oxvHFDH85q38jrsiTEgrml0BcY7JwbCEQD\ndZxzb5jZ1QeN2QTEA1nOuapAXUoPOP+MmU0GJgMkJydr15JIgP135XbGzUhjc24+1/dN5C8XnUKs\nGthVSkF71s1sLDAWwL+l8JdDAgFgFnAt8DUwHJir4wkiobNr/wEe/iCDGd9vom1cLNNvPoOerdTA\nrjIL+b8CzrmHgMVmNguYAvzLOZcJ7ASuDHU9IpWRmfFh2hYemJXO7rwi/nheO247rx01qqqBXWUX\nklAws/nAfP/l+w9aXgD8JhQ1iEipbXsKGP9eOnOWbiWpRV2mjuhD5+aHO2NcKiPtNBSpJMyMd5Zk\nMXF2BoXFPsZc3JGRZ7WmqhrYyUEUCiKVwMadeYydkcYXmTvondiAxy9Lok2cGtjJLykURCJYic94\n/at1PDlnBVWiHBMv7crveieogZ0ckUJBJEKt2rqX0SmpfL9hN/1OiePRoUk0rxfjdVlSwSkURCJM\nUYmPl+av5u9zM4mtUYW/XdGdId2bq4GdlItCQSSCpGbt5p7pqSzfspdB3ZoxYXAXGtWq4XVZEkYU\nCiIRoKCohGc+XcnLC9cQV7sGL1+TzIWdm3hdloQhhYJImFu0JocxKamsy8njyl7xjB3YiboxamAn\nJ0ahIBKm9hYU8fhHy3nzmw3EN4hh2sg+nNlODezk5CgURMLQvOXbGDczjS17ChjRtzV/+VUHalbX\nn7OcPP0WiYSRnfsP8PDsDGb+sIn2jWuRcsuZ9Eio73VZEkEUCiJhwMyYnZrNhFlLyc0v4vbz2nGr\nGthJECgURCq4rXsKuO/ddD7N2Eq3lnV588
 Y+dGyqBnYSHAoFkQrKzPjPdxt55MNlHCj2MW5gR0b0\nVQM7CS6FgkgFtCEnjzEzUvlqdQ59Wjdg0mXdSGwU63VZUgkoFEQqkBKf8c8v1/LXT1ZQNSqKR4cm\ncWWveDWwk5BRKIhUECu2lDaw+3Hjbs7v2JiJQ7vSrK4a2EloKRREPHag2McL8zN5fl4mtaOr8eyV\n3Rl8qhrYiTcUCiIe+mljaQO7FVv3MqR7c+4f1JmGamAnHlIoiHgg/0AJT3+6gilfrKVx7WimXJvM\n+Z3UwE68p1AQCbGvVu9g7Iw01ufk8bs+CYy5uCN1otXATioGhYJIiOwpKOKxD5fz72830KphTf59\n4+mc0bah12WJ/IxCQSQEPl+2lXtnprNtbwGjzmnDXRd0IKa6WlRIxaNQEAminH2FPPh+BrN+2swp\nTWrzj9/35NT4el6XJXJEQQsF51w0sACo4V/PdDN74JAx1wFPApv8i54zs1eCVZNIqJgZs37azIPv\nZ7C3oIi7LujALf3aUr2qWlRIxRbMLYVC4Dwz2+ecqwZ84Zz7yMwWHTLuP2Z2WxDrEAmp7Nx87puZ\nzufLt3FqfD2eHN6NDk1qe12WSLkcMxScc38E3jCzXcfzwGZmwD7/1Wr+LzvuCkXChM9nvPXdRh77\ncBlFPh/3XdKJ6/u2popaVEgYKc+WQhPgO+fc98CrwBz/C/4xOeeqAEuAdsDzZvbNYYZd5pw7B1gJ\n3GVmG8tXukjFsW7HfsbMSGXRmp2c2bYhjw/rRkLDml6XJXLcXHle313p++0vAq4HkoG3gSlmtrpc\nK3GuHjAT+KOZpR+0vCGwz8wKnXM3AVeY2XmHuf8oYBRAQkJCz/Xr15dntSJBV1zi49Uv1/LUJyup\nXjWK+y7pxOXJ8WpRIRWOc26JmSUfa1y5jnr5twy2+L+KgfrAdOfcE+W8/25gHjDgkOU5Zlbov/oK\n0PMI959sZslmlhwXF
 1eeVYoE3bLsPQx78Sse/XA5Z7eP47M/ncsVvRIUCBLWynNM4Q7gGmAHpS/c\nd5tZkXMuClgF3HOE+8UBRWa22zkXA1wITDpkTDMzy/ZfHQwsO+GZiIRIYXEJz8/N5IX5q6kbU43n\nfncalyQ1UxhIRCjPMYUGwDAz+9k+GzPzOecGHeV+zYDX/ccVooC3zWy2c+4hYLGZzQJud84NpnTr\nYydw3YlMQiRUvt+wi9HTU1m1bR9DT2vB/YM6Uz+2utdliQRMuY4pVCTJycm2ePFir8uQSibvQDF/\nnbOSf361lmZ1onlkWBL9T2nsdVki5VbeYwp6R7PIMXyxagdjZqSStSufq09PYPSAjtRWAzuJUAoF\nkSPIzS/ikQ8yeHtxFq0bxfKfUafTp40a2ElkUyiIHMacpVsY/246O/YVctM5bbjrwg5EV1MDO4l8\nCgWRg+zYV8gDs5byQWo2HZvW5pVrk+nWUg3spPJQKIhQ2sBu5g+beGh2BnmFJfz5wg7c3K8t1aqo\ngZ1ULgoFqfQ27c7n3plpzF+xnR4J9XhieDfaNVYDO6mcFApSafl8xpvfrOfxj5bjM3jg15255oxE\nNbCTSk2hIJXSmu37GJOSxrfrdnJ2+0Y8OjSJ+AZqYCeiUJBKpbjEx8sL1/LMZyuJrhrFE8O78Zue\nLdWiQsRPoSCVxtLNuYxOSSV90x4GdGnKQ5d2oXHtaK/LEqlQFAoS8QqKSvj73FW89N811K9ZnRev\n6sHFSc28LkukQlIoSERbsn4n90xPZfX2/VzWoyXjB3WiXk01sBM5EoWCRKT9hcU8OWcFr3+9juZ1\nY3h9RG/O7aDP4hA5FoWCRJwFK7czdkYam3Pzueb0Vtw9oCO1auhXXaQ89JciEWN33gEmfrCM6Uuy\naBMXyzs3nUFyYgOvyxIJKwoFiQgfp2dz37tL2ZV3gD/0a8vt57dXAzuRE6BQkLC2bW8BD7y3lI/S\n
 t9CleR1eu74XXVvU9boskbClUJCwZGZMX5LFxA+WkV9UwugBHRl5dms1sBM5SQoFCTsbd+YxbmYa\nC1ftILlVfSYN70bbuFpelyUSERQKEjZ8PuNfi9Yz6ePlOOChIV24uk8rotTATiRgFAoSFjK37WNM\nSiqL1+/i3A5xPDK0Ky3rq4GdSKApFKRCKyrxMXnBGp79bBU1a1Th6ctPZehpLdTATiRIFApSYaVv\nyuWe6alkZO9hYFJTHhzclbjaNbwuSySiKRSkwikoKuHZz1cxecEaGsRW56WrezKga1OvyxKpFIIW\nCs65aGABUMO/nulm9sAhY2oAU4GeQA5whZmtC1ZNUvF9t24no6ensmbHfq5IjmfcwE7UrVnN67JE\nKo1gbikUAueZ2T7nXDXgC+fcR2a26KAxNwC7zKydc+5KYBJwRRBrkgpqX2ExT3y8nKlfr6dl/Rje\nuKEPZ7Vv5HVZIpVO0ELBzAzY579azf9lhwwbAkzwX54OPOecc/77SiUxb8U27p2RRvaeAq7vm8hf\nLjqFWDWwE/FEUP/ynHNVgCVAO+B5M/vmkCEtgI0AZlbsnMsFGgI7glmXVAy79h/g4dkZzPhhE23j\nYpl+8xn0bKUGdiJeCmoomFkJ0N05Vw+Y6Zzrambpx/s4zrlRwCiAhISEAFcpoWZmfJi2hQdmpbM7\nr4jb+rfjj+e3o0ZVNbAT8VpIttHNbLdzbh4wADg4FDYB8UCWc64qUJfSA86H3n8yMBkgOTlZu5bC\n2LY9BYx/L505S7eS1KIuU0f0oXPzOl6XJSJ+wTz7KA4o8gdCDHAhpQeSDzYLuBb4GhgOzNXxhMhk\nZryzOIuHP8jgQLGPsRd35IazWlNVDexEKpRgbik0A173H1eIAt42s9nOuYeAxWY2C5gC/Ms5lwns\nBK4MYj3ikY078xg7I40vMnfQu3UDHh+WRBs1sBOpkIJ59lEqcNphlt9/0OUC4
 DfBqkG8VeIzXv9q\nHU/OWUGUg4cv7cpVvRPUwE6kAtN5fxIUq7buZXRKKt9v2E2/U+J4dGgSzevFeF2WiByDQkECqqjE\nx0vzV/P3uZnE1qjC367ozpDuzdXATiRMKBQkYFKzdnPP9FSWb9nLr09tzgO/7kyjWmpgJxJOFApy\n0gqKSnjm05W8vHANjWrV4OVrkrmwcxOvyxKRE6BQkJOyaE0OY2eksXbHfn7bO54xF3eibowa2ImE\nK4WCnJC9BUU8/tFy3vxmAwkNajJtZB/ObKcGdiLhTqEgx23e8m2Mm5nG1j0FjDyrNX+6qAM1q+tX\nSSQS6C9Zym3n/gM89P5S3v1xMx2a1OKFq87ktIT6XpclIgGkUJBjMjNmp2YzYdZS9hQUccf57bm1\nfzuqV1WLCpFIo1CQo9qSW8B976bz2bKtnNqyLpOG96FjUzWwE4lUCgU5LDPjre828ugHyyjy+bh3\nYCdGnNWaKmpRIRLRFAryC+tz9jMmJY2v1+RwepsGPD6sG4mNYr0uS0RCQKEgZUp8xj+/XMtfP1lB\ntagoHh2axJW94tXATqQSUSgIACu27OWelFR+2rib8zs2ZuLQrjSrqwZ2IpWNQqGSO1Ds44X5mTw/\nL5Pa0dX4v9+exq+7NVMDO5FKSqFQif24cTejp6eyYuteBvsb2DVUAzuRSk2hUAnlHyjhqU9W8OqX\na2lcO5op1yZzfic1sBMRhUKl89XqHYxJSWPDzjx+1yeBMRd3pE60GtiJSCmFQiWxp6CIxz5cxr+/\n3Uhiw5r8+8bTOaNtQ6/LEpEKRqFQCXyWsZV7301j+95CbjqnDXde0IGY6lW8LktEKiCFQgTL2VfI\nhPczeP+nzXRsWpvJv0/m1Ph6XpclIhWYQiECmRnv/biZB99fyr7CYu66oAO39GurBnYickwKhQiz\neXc+972bztzl2+geX48nhnejQ5PaXpclImFCoRAhfD5j
 2rcbePyj5ZT4jPGDOnPdmYlqYCcixyVo\noeCciwemAk0AAyab2bOHjOkHvAes9S+aYWYPBaumSLV2x37GpKTyzdqd9G3XkMeGdiOhYU2vyxKR\nMBTMLYVi4M9m9r1zrjawxDn3qZllHDJuoZkNCmIdEau4xMeUL9by9KcrqV41ikmXJXF5crxaVIjI\nCQtaKJhZNpDtv7zXObcMaAEcGgpyApZl72F0SiqpWblc2LkJEy/tSpM60V6XJSJhLiTHFJxzicBp\nwDeHufkM59xPwGbgL2a2NBQ1havC4hKen5vJC/NXU69mNZ7/XQ8GJjXV1oGIBETQQ8E5VwtIAe40\nsz2H3Pw90MrM9jnnBgLvAu0P8xijgFEACQkJQa644lqyfhejU1LJ3LaPYT1aMP6SztSPre51WSIS\nQZyZBe/BnasGzAbmmNnT5Ri/Dkg2sx1HGpOcnGyLFy8OXJFhIO9AMU/OWcFrX62jWZ1oHhmWRP9T\nGntdloiEEefcEjNLPta4YJ595IApwLIjBYJzrimw1czMOdcbiAJyglVTOPpi1Q7Gzkxl4858rjmj\nFfcM6EitGjqTWESCI5ivLn2B3wNpzrkf/cvGAQkAZvYSMBy4xTlXDOQDV1owN13CSG5+EY98kMHb\ni7No3SiWt286g96tG3hdlohEuGCeffQFcNSjn2b2HPBcsGoIV3OWbmH8u+nk7D/ALf3acsf57Ymu\npgZ2IhJ82g9RgWzfW8iEWUv5IC2bTs3qMOXaXiS1rOt1WSJSiSgUKgAzY+YPm3hodgZ5hSXc/atT\nGHVOG6pVUQM7EQkthYLHNu3OZ9yMNP67cjs9W9Vn0mXdaNe4ltdliUglpVDwiM9nvPHNeiZ9tBwD\nJvy6M9eckUiUGtiJiIcUCh5YvX0fY1JS+W7dLs5u34hHhyYR30AN7ETEewqFECou8fHywrU889lK\noqtG8eTwbgzv2VItKkSkwlAohMj
 SzbmMTkklfdMeBnRpykOXdqFxbTWwE5GKRaEQZAVFJTw3N5OX\n/ruaejWr8+JVPbg4qZnXZYmIHJZCIYgWr9vJ6JRUVm/fz2U9WjJ+UCfq1VQDOxGpuBQKQbC/sLSB\n3etfr6N53RimjujNOR3ivC5LROSYFAoBtmDldsbOSGNzbj7XnF7awC5WDexEJEzo1SpAducdYOIH\ny5i+JIs2cbG8c9MZJCeqgZ2IhBeFQgB8lJbN+PeWsivvALf2b8sfz1MDOxEJTwqFk7BtbwEPvLeU\nj9K30KV5HV4f0YsuzdXATkTCl0LhBJgZ05dkMfGDZeQXqYGdiEQOhcJx2rgzj3Ez01i4age9Euvz\n+GXdaBufgoMsAAAHZElEQVSnBnYiEhkUCuXk8xlTv17HE3NW4ICHh3Thqj6t1MBORCKKQqEcMrft\nZXRKGkvW7+LcDnE8OiyJFvVivC5LRCTgFApHUVTiY/KCNTz72Spiqlfh6ctPZehpLdTATkQilkLh\nCNI35XLP9FQysvdwSVIzJgzuQlztGl6XJSISVAqFQxQUlfDs56uYvGANDWKr89LVPRnQtanXZYmI\nhIRC4SDfrt3JmJRU1uzYzxXJ8Ywb2Im6Nat5XZaISMgoFIB9hcVM+mg5/1q0npb1Y3jjhj6c1b6R\n12WJiIRcpQ+FeSu2ce+MNLL3FDCib2v+8qsO1Kxe6X8sIlJJBe3VzzkXD0wFmgAGTDazZw8Z44Bn\ngYFAHnCdmX0frJoOtmv/AR6encGMHzbRvnEtpt98Jj1b1Q/FqkVEKqxg/ktcDPzZzL53ztUGljjn\nPjWzjIPGXAy093/1AV70fw8aM+ODtGweeG8puflF3H5eO249rx01qqqBnYhI0ELBzLKBbP/lvc65\nZUAL4OBQGAJMNTMDFjnn6jnnmvnvG3Bb9xQw/t10PsnYSlKLurwxsg+dmtUJxqpERMJSSHaeO+cS\ngdOAbw65qQ
 Ww8aDrWf5lAQ+Fecu3cftbP3Cg2MfYiztyw1mtqaoGdiIiPxP0UHDO1QJSgDvNbM8J\nPsYoYBRAQkLCCdXRulEsPRLqM2FwF1o3ij2hxxARiXRB/VfZOVeN0kB408xmHGbIJiD+oOst/ct+\nxswmm1mymSXHxZ3YZx0nNorl9RG9FQgiIkcRtFDwn1k0BVhmZk8fYdgs4BpX6nQgN1jHE0RE5NiC\nufuoL/B7IM0596N/2TggAcDMXgI+pPR01ExKT0m9Poj1iIjIMQTz7KMvgKO2E/WfdXRrsGoQEZHj\no9NvRESkjEJBRETKKBRERKSMQkFERMooFEREpIwrPQEofDjntgPrT/DujYAdASwnHGjOlYPmXDmc\nzJxbmdkx3/0bdqFwMpxzi80s2es6Qklzrhw058ohFHPW7iMRESmjUBARkTKVLRQme12ABzTnykFz\nrhyCPudKdUxBRESOrrJtKYiIyFFEZCg45wY451Y45zKdc2MOc3sN59x//Ld/4/9kuLBWjjn/yTmX\n4ZxLdc597pxr5UWdgXSsOR807jLnnDnnwv5MlfLM2Tl3uf+5XuqcmxbqGgOtHL/bCc65ec65H/y/\n3wO9qDNQnHOvOue2OefSj3C7c879n//nkeqc6xHQAswsor6AKsBqoA1QHfgJ6HzImD8AL/kvXwn8\nx+u6QzDn/kBN/+VbKsOc/eNqAwuARUCy13WH4HluD/wA1Pdfb+x13SGY82TgFv/lzsA6r+s+yTmf\nA/QA0o9w+0DgI0q7UJ8OfBPI9UfilkJvINPM1pjZAeAtYMghY4YAr/svTwfO938oULg65pzNbJ6Z\n5fmvLqL0U+7CWXmeZ4CHgUlAQSiLC5LyzPlG4Hkz2wVgZttCXGOglWfOBtTxX64LbA5hfQFnZguA\nnUcZMgSYaqUWAfWcc80Ctf5IDIUWwMaDrmf5lx12jJkVA7lAw5BUFxzlmfPBbqD0P41wdsw
 5+zer\n483sg1AWFkTleZ47AB2cc1865xY55waErLrgKM+cJwBXO+eyKP3grj+GpjTPHO/f+3EJ5ievSQXk\nnLsaSAbO9bqWYHLORQFPA9d5XEqoVaV0F1I/SrcGFzjnksxst6dVBddvgdfM7Cnn3BnAv5xzXc3M\n53Vh4SgStxQ2AfEHXW/pX3bYMc65qpRucuaEpLrgKM+ccc5dANwLDDazwhDVFizHmnNtoCsw3zm3\njtJ9r7PC/GBzeZ7nLGCWmRWZ2VpgJaUhEa7KM+cbgLcBzOxrIJrSHkGRqlx/7ycqEkPhO6C9c661\nc646pQeSZx0yZhZwrf/ycGCu+Y/ghKljztk5dxrwD0oDIdz3M8Mx5mxmuWbWyMwSzSyR0uMog81s\nsTflBkR5frffpXQrAedcI0p3J60JZZEBVp45bwDOB3DOdaI0FLaHtMrQmgVc4z8L6XQg18yyA/Xg\nEbf7yMyKnXO3AXMoPXPhVTNb6px7CFhsZrOAKZRuYmZSekDnSu8qPnnlnPOTQC3gHf8x9Q1mNtiz\nok9SOeccUco55znARc65DKAEuNvMwnYruJxz/jPwsnPuLkoPOl8Xzv/kOef+TWmwN/IfJ3kAqAZg\nZi9RetxkIJAJ5AHXB3T9YfyzExGRAIvE3UciInKCFAoiIlJGoSAiImUUCiIiUkahICIiZRQKIiJS\nRqEgIiJlFAoiJ8k518vf1z7aORfr/xyDrl7XJXIi9OY1kQBwzk2ktL1CDJBlZo95XJLICVEoiASA\nvy/Pd5R+bsOZZlbicUkiJ0S7j0QCoyGlvaVqU7rFIBKWtKUgEgDOuVmUfipYa6CZmd3mcUkiJyTi\nuqSKhJpz7hqgyMymOeeqAF85584zs7le1yZyvLSlICIiZXRMQUREyigURESkjEJBRETKKBRERKSM\nQkFERMooFEREpIxCQUREyigURESkzP8DkkYtiInuClwAAAAASUVORK
 5CYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f3cce2f9cd0>"
+       "<matplotlib.figure.Figure at 0x7fedeac59588>"
       ]
      },
      "metadata": {},
@@ -86,7 +87,7 @@
     "plt.plot(gx, gy,  label='y=f(x)')\n",
     "plt.xlabel('x')\n",
     "plt.ylabel('y')\n",
-    "plt.legend(loc='best')\n"
+    "plt.legend(loc='best')"
    ]
   },
   {
@@ -102,14 +103,12 @@
   {
    "cell_type": "code",
    "execution_count": 4,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "[<matplotlib.lines.Line2D at 0x7f3c7b71a410>]"
+       "[<matplotlib.lines.Line2D at 0x7fede8b1c588>]"
       ]
      },
      "execution_count": 4,
@@ -118,9 +117,9 @@
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXoAAAD8CAYAAAB5Pm/hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFcVJREFUeJzt3X+MZWdZwPHvQ7e4pVscYhfYdjsulPoLYwFna1OJWTCM\ndGls3PSPpkIjMVkWKsGo8dcfEGmMmhiDZJVNRaJEKzG6CxULioFKCRa6W+nSUjS7S7G73Vha3cJs\nZzUDj3+cM/bu7Z2Zc+/ce8+P+X6Syb33nDP3Pj3pPvfMc573fSMzkSR11/PqDkCSNFkmeknqOBO9\nJHWciV6SOs5EL0kdZ6KXpI4z0UtSx5noJanjTPSS1HGb6vrgSy+9NHfs2FHXx0tSKx05cuTJzNw6\nzO9USvQR8SjwLeDbwFJmzvXt3wV8DPhauelgZr53tffcsWMHhw8fHiZWSdrwIuLrw/7OMFf0r8vM\nJ1fZf29m3jBsAJKkybJGL0kdVzXRJ/BPEXEkIvaucMx1EXE0Ij4REa8cU3ySpHWqWrp5bWaeiogX\nA5+KiK9m5md79j8AzGbmQkTsBj4KXNX/JuWXxF6A2dnZdYYuSaqi0hV9Zp4qH58ADgHX9O3/ZmYu\nlM/vBi6MiEsHvM8dmTmXmXNbtw5101iSWm9xEe68E26/vXg8d246n7vmFX1EXAw8LzO/VT6fB97b\nd8xLgf/MzIyIayi+QJ6aRMCS1Eb33w/z87C0BGfPwsUXw223wT/+I+zcOdnPrlK6eQlwKCKWj78z\nMz8ZEfsAMvMAcBPw9ohYAhaBm9OlqyQJKK7k5+fhzJlnty0sFI/z83D6NGzePLnPXzPRZ+YJ4OoB\n2w/0PN8P7B9vaJLUDYcOFVfygywtwcGDcMstk/v82kbGStKoFheL5Hn8OFx5JezZM9kr4vU6frwo\n1wxy9iycODHZzzfRS2qVOmvdo7ryyiLO5XJNr4svh
 pe/fLKf74ApSa3RW+teWIDM4vHMmWL7tLpY\nhrVnD2xa4bJ606Zi/ySZ6CW1RpVadxNt3lz8xTEzA1u2QETxODNTbJ902cnSjaTWqLvWvR47d8Lj\njxdfVidOFOWaad1bMNFLao26a93rddFFk+2uWYmlG0mtUXetu61M9JJao+5ad1tZupHUKnXWutvK\nRC+pdeqqdbeVpRtJ6jgTvSR1nIlekjrORC9JHWeil6SOM9FLUseZ6CWp40z0ktRxJnpJ6jgTvSR1\nnIlekjrORC9JHWeil6SOqzR7ZUQ8CnwL+DawlJlzffsD+ENgN/AM8HOZ+cB4Q5Wk+i0uFlMkHz9e\nrHjVhimSh5mm+HWZ+eQK+64Hrip/fgz4QPkoSSNpYkK9/36Yny8WIj97tli+8LbbikVPdu6sN7bV\njGs++huBD2dmAvdFxExEbMvM02N6f0kbSBMT6uJiEdOZM89uW167dn4eTp+u/4toJVVr9An8U0Qc\niYi9A/ZfDjzW8/pkuU2ShtKbUBcWILN4PHOm2H7uXD1xHTpUfPEMsrQEBw9ON55hVE30r83MV1GU\naG6LiJ8Y5cMiYm9EHI6Iw9/4xjdGeQtJHdfUhHr8ePHXxSBnzxbLGjZVpUSfmafKxyeAQ8A1fYec\nAq7oeb293Nb/Pndk5lxmzm3dunW0iCV1WlMT6pVXFiWkQS6+uFi7tqnWTPQRcXFEXLL8HJgHHuo7\n7C7g1ihcCzxtfV7SKJqaUPfsgU0r3NXctKnY31RVruhfAnwuIh4Evgj8fWZ+MiL2RcS+8pi7gRPA\nMeBPgHdMJFpJndfUhLp5c3EzeGYGtmyBiOJxZqbY3tQbsVCh6yYzTwBXD9h+oOd5AreNNzRJG9Fy\nQu3vutm0qf6EunMnPP54cR/hxInir4smtH2uZVztlZI0Nk1OqBddBLfcUncUwzHRS2qkNibUpnKu\nG0nqOBO9JHWcpRtJjdO0eW6a
 Fs+wTPSSGqVp89w0LZ5RRNEZOX1zc3N5+PDhWj5bUjMtLsJll50/\ncdiymZnpTxzWtHgAIuJI/1Txa7FGL6kxmjbPTdPiGZWJXlJjNG2em6bFMypr9JIaY3mem+V53nsN\nmudm0jdJh42nqazRS2qMc+dg27ZqNfFBN0mXp0kY103SYeKZFmv0klqt6sRh01qcpM0TmfWydCOp\nUarMc1PlJum4pk9o8rw7VZnoJdVuUK19tUQ97ZukbZ93x0QvqVajDEjqyk3SabFGL6k2q9Xad+0a\nfBMUmrs4SVOZ6CXVZrVa+zPPwOWXF1f8/bpyk3RaLN1Iqs1qtXYokv38/OA2xi7cJJ0WE73UcU2e\neXG1Wvuy1bpo2n6TdFpM9FKHNX3mxT17inhW06apBprKGr3UUdMaVLQey7X2F7xg5WPsolk/E73U\nUW2ZeXHnTjh5cuVkbxfN+pnopY5q08yLL3oR3HOPXTSTUrlGHxEXAIeBU5l5Q9++XcDHgK+Vmw5m\n5nvHFaSk4bVtUJFdNJMzzM3YdwGPAC9cYf+9/V8Akuqz2o3OppZD7KKZjEqlm4jYDrwJ+OBkw5E0\nLg4q0rKqV/TvA34VuGSVY66LiKPAKeBXMvPh9QYnNVGT+9L7WQ4RVEj0EXED8ERmHilr8YM8AMxm\n5kJE7AY+Clw14L32AnsBZmdnRw5aqkvT+9IHsRyiNVeYiojfAd4CLAGbKWr0BzPzzav8zqPAXGY+\nudIxrjCltllchMsua9ZqQ9p4JrLCVGb+RmZuz8wdwM3Ap/uTfES8NCKifH5N+b5PDROI1HRt6UuX\n+o08BUJE7APIzAPATcDbI2IJWARuzroWo5UmpE196VKvoRJ9Zt4D3FM+P9CzfT+wf5yBSU3Ttr50\naZkjY6WKXOxCbWWilyqyL11t5TTF0hDsS1cbmeilIdmXrraxdCNJHWeil6SOM9FLUseZ6CWp40z0\nktRxJnp
 J6jgTvSR1nIlekjrORC9JHefIWKkD2rS8oabPRC+1XBuXN9R0meilFltcLJJ87/KGy/Pl\nz8+7vKEK1uilFnN5Q1VhopdazOUNVYWJXmqx5eUNB3F5Qy0z0asRFhfhzjvh9tuLx3Pn6o6oHVze\nUFV4M1a1s2tkdMvLG/afv02bXN5QzzLRq1Z2jayfyxtqLSZ61apK14jL9q3N5Q21Gmv0qpVdI9Lk\nVU70EXFBRPxrRHx8wL6IiPdHxLGIOBoRrxlvmOoqu0akyRvmiv5dwCMr7LseuKr82Qt8YJ1xaYOw\na0SavEo1+ojYDrwJ+G3glwYcciPw4cxM4L6ImImIbZl5enyhatp6J8q64opi22OPjXfSLLtGpMmr\nejP2fcCvApessP9y4LGe1yfLbecl+ojYS3HFz+zs7FCBarr6Wx4zn923Zct42x83YteIs01qmtZM\n9BFxA/BEZh6JiF3r+bDMvAO4A2Bubi7XOFw1GdTy2GsS7Y8bqWvEcQOatio1+h8HfjoiHgU+Arw+\nIv6i75hTwBU9r7eX29RCq7U89nLSrOH1fokuLBR/KS0sFK/n5x0RrMlYM9Fn5m9k5vbM3AHcDHw6\nM9/cd9hdwK1l9821wNPW59trtZbHXrY/Ds/ZJlWHkQdMRcQ+gMw8ANwN7AaOAc8Abx1LdKrFcsvj\ncolmJbY/Ds9xA6rDUIk+M+8B7imfH+jZnsBt4wxM9dmzp6gZr8X2x+Gt9iXqF6cmxZGxeo7llseZ\nmaLDJuL8/Vu2FPtsfxye4wZUB+e60UD9LY/btxfbT57cGO2Pk+K4AdXBRK8VbaSWx2naiOMGVC8T\nvVQDv0Q1TdboJanjTPSS1HEmeknqOGv0G0SbJtFqU6xSG5joN4A2TaLVpliltojMeiaRnJuby8OH\nD9fy2RvJ4iJcdtngmShnZpq1+HabYpXqEhFHMnNumN+xRt9xbZpEq02xSm1iou+4Nk2i
 1aZYpTYx\n0XdcmxbfblOsUptYo2+hYbpSzp2DbdvWV/eeVhfMOGKVum6UGr1dNy0zbFfKeifRmmYXTJMm/LLF\nU13iFX2LrKcrZTlxDTOJVl1dMKPEOk6DvtyWv2xs8VTdvKLvuCpdKStNlDXKJFrr+bz1qHPCr0EL\no09iMXRpmrwZ2yLj6EpZXIQ774Tbby8eV1uMeiN2wdjiqS7yir5F1rsM3bD19o247N1G/HJT93lF\n3yLrWYautySxsACZxeOZM8X2QVf2bVn2bpi/UtZii6e6yETfIoPWcq26fusoJYn1fN603H9/ccP4\nbW+D97yneNy2rdg+irZ8uUnDsHTTMqMuQzdqSaLJy95N4sZpk1o8pXEx0bfQKF0p66m3N3XZu0l1\nBTX5y00axZqJPiI2A58Fvqs8/m8y8z19x+wCPgZ8rdx0MDPfO95QtR579hQ3Xgdpa0likjdOm/rl\nJo2iyhX9/wCvz8yFiLgQ+FxEfCIz7+s77t7MvGH8IWoculiS2IhdQdIo1kz0WQydXf6ndGH5U89w\nWq1L10oSXfwrRZqESjX6iLgAOAK8AvijzPzCgMOui4ijwCngVzLz4QHvsxfYCzA7Ozty0Bpdl0oS\nXfwrRZqEoea6iYgZ4BDwzsx8qGf7C4HvlOWd3cAfZuZVq72Xc920UxMn+6p7bhxpmkaZ62boSc0i\n4t3AM5n5+6sc8ygwl5lPrnSMib59nOxLqt9ElhKMiK3llTwRcRHwBuCrfce8NCKifH5N+b5PDROI\nmm2UkbWSmqHKyNhtwGfK+vv9wKcy8+MRsS8i9pXH3AQ8FBEPAu8Hbs665j/WRDjZl9ReVbpujgKv\nHrD9QM/z/cD+8YamJnGyL6m9nOtGlTjZl9ReJnpV4mRfUnuZ6FVJG2aylDSYk5qpsq6NrJU2ChO9\nhtKlkbXSRmHpRpI6ziv6ITRx+L8krcVEX9GwC2tLUlOY6CuYxJJ
 1kjQt1ugrcPi/pDYz0Vfg8H9J\nbWair8Dh/5LazERfgcP/JbWZib4Ch/9LajO7bipy+L+ktjLRD8Hh/5LayNKNJHWcV/Qd4hQNkgYx\n0TfIehK1UzRIWknUtYb33NxcHj58uJbPbqJBiXrTpmqJenERLrvs/Ckals3MOEWD1CURcSQz54b5\nHWv0DdA7l87CAmQWj2fOFNvPnVv9952iQdJqTPQNsN5E7RQNklZjom+A9SZqp2iQtJo1E31EbI6I\nL0bEgxHxcET81oBjIiLeHxHHIuJoRLxmMuF203oTtVM0SFpNlSv6/wFen5lXA68C3hgR1/Ydcz1w\nVfmzF/jAWKPsuPUmaqdokLSaNdsrs2jLKZfZ4MLyp79V50bgw+Wx90XETERsy8zTY422o5YT9Upd\nN1UStVM0SFpJpT76iLgAOAK8AvijzPxC3yGXA4/1vD5ZbjPRVzSORO0UDZIGqZToM/PbwKsiYgY4\nFBE/nJkPDfthEbGXorTD7OzssL/eeSZqSZMwVNdNZp4BPgO8sW/XKeCKntfby239v39HZs5l5tzW\nrVuHjVWSNIIqXTdbyyt5IuIi4A3AV/sOuwu4tey+uRZ42vq8JDVDldLNNuDPyzr984C/zsyPR8Q+\ngMw8ANwN7AaOAc8Ab51QvJKkIVXpujkKvHrA9gM9zxO4bbyhSZLGwZGxktRxJnpJ6jgTvSR1nAuP\n9HGVJkldY6Lv4SpNkrrIRF/qXfxj2UI5w8/8vKs0SWova/QlV2mS1FUm+pKrNEnqKhN9yVWaJHWV\nib7kKk2SuspEX3KVJkldZddND1dpktRFnU30ow58cvEPSV3TyUTvwCdJelbnEr0DnyTpfJ27GevA\nJ0k6X+cSvQOfJOl8nUv0DnySpPN1LtE78EmSzte5RO/AJ0k6X+e6bsCBT5LUq5OJHhz4JEnLOle6\nkSSdb81EHxFXRMRnIuIrEfFwRLxrwDG7Iu
 LpiPhS+fPuyYQrSRpWldLNEvDLmflARFwCHImIT2Xm\nV/qOuzczbxh/iJKk9Vjzij4zT2fmA+XzbwGPAJdPOjBJ0ngMVaOPiB3Aq4EvDNh9XUQcjYhPRMQr\nxxCbJGkMKnfdRMQW4G+BX8zMb/btfgCYzcyFiNgNfBS4asB77AX2AszOzo4ctCSpukpX9BFxIUWS\n/8vMfM60YJn5zcxcKJ/fDVwYEZcOOO6OzJzLzLmtW7euM3RJUhVVum4C+FPgkcz8gxWOeWl5HBFx\nTfm+T40zUEnSaKqUbn4ceAvw5Yj4UrntN4FZgMw8ANwEvD0iloBF4ObMzAnEK0ka0pqJPjM/B8Qa\nx+wH9o8rKEnS+DgyVpI6rlVz3Yy64LckbWStSfQu+C1Jo2lFonfBb0kaXStq9C74LUmja0Wid8Fv\nSRpdKxK9C35L0uhakehd8FuSRteKRO+C35I0ulZ03YALfkvSqFqT6MEFvyVpFK0o3UiSRmeil6SO\nM9FLUseZ6CWp46Ku9UEi4hvA12v58Mm7FHiy7iAayPPyXJ6TwTwvz7V8Tr43M4dai7W2RN9lEXE4\nM+fqjqNpPC/P5TkZzPPyXOs5J5ZuJKnjTPSS1HEm+sm4o+4AGsrz8lyek8E8L8818jmxRi9JHecV\nvSR1nIl+HSLijRHxbxFxLCJ+fcD+n42IoxHx5Yj4fERcXUec07TWOek5bmdELEXETdOMry5VzktE\n7IqIL0XEwxHxz9OOcdoq/Pv57oj4u4h4sDwnb60jzmmKiA9FxBMR8dAK+yMi3l+es6MR8ZpKb5yZ\n/ozwA1wAHAdeDjwfeBD4ob5jrgNeVD6/HvhC3XHXfU56jvs0cDdwU91xN+G8ADPAV4DZ8vWL6467\nAefkN4HfK59vBf4LeH7dsU/4vPwE8BrgoRX27wY+AQRwbdWc4hX96K4BjmXmicz8X+AjwI29B2Tm\n5zPzv8uX9wHbpxzjt
 K15TkrvBP4WeGKawdWoynm5BTiYmf8BkJldPzdVzkkCl0REAFsoEv0Kq0d3\nQ2Z+luK/cyU3Ah/Own3ATERsW+t9TfSjuxx4rOf1yXLbSn6e4pu4y9Y8JxFxOfAzwAemGFfdqvy/\n8n3AiyLinog4EhG3Ti26elQ5J/uBHwQeB74MvCszvzOd8Bpr2LwDtGw++raKiNdRJPrX1h1LA7wP\n+LXM/E5xoabSJuBHgZ8ELgL+JSLuy8x/rzesWv0U8CXg9cCVwKci4t7M/Ga9YbWPiX50p4Arel5v\nL7edJyJ+BPggcH1mPjWl2OpS5ZzMAR8pk/ylwO6IWMrMj04nxFpUOS8ngacy8yxwNiI+C1wNdDXR\nVzknbwV+N4vi9LGI+BrwA8AXpxNiI1XKO/0s3YzufuCqiHhZRDwfuBm4q/eAiJgFDgJv2SBXZmue\nk8x8WWbuyMwdwN8A7+h4kocK5wX4GPDaiNgUES8Afgx4ZMpxTlOVc/IfFH/hEBEvAb4fODHVKJvn\nLuDWsvvmWuDpzDy91i95RT+izFyKiF8A/oGig+BDmflwROwr9x8A3g18D/DH5RXsUnZ4oqaK52TD\nqXJeMvORiPgkcBT4DvDBzBzYYtcFFf9fuR34s4j4MkWXya9lZqdntIyIvwJ2AZdGxEngPcCF8P/n\n5G6KzptjwDMUf/Ws/b5ly44kqaMs3UhSx5noJanjTPSS1HEmeknqOBO9JHWciV6SOs5EL0kdZ6KX\npI77P/o8W9CbuMwEAAAAAElFTkSuQmCC\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAFlFJREFUeJzt3X+QXXV5x/HPBzaQH4vcDlk1QDAlAlO1ReyG6uhYhJKh\ngmFcsaQZ1HTQVCaoHW0daWcYxXEcp1b7g05pps5UsRQsJTZFUJiCo3YKZgMBQaCTRCyQKEt0kQ27\n0a1P/zj3Njebu/eeu7n3nHPPeb9mdu695xzueTizPHt4zvP9fh0RAgCUyzF5BwAA6D2SOwCUEMkd\nAEqI5A4AJURyB4ASIrkDQAmR3AGghEjuAFBCJHcAKKGhvE68fPnyWLVqVV6nB4CBtGPHjuciYqTT\ncbkl91WrVml8fDyv0wPAQLL9wzTHUZYBgBIiuQNACZHcAaCESO4AUEK5PVAFgLxNT0tbt0q7d0ur\nV0tjY9LixeU4H8kdQCVt3y6tXSvNzkoHDkjLlkmbN0t33SWtWTP453NeKzGNjo4GrZAA8jA9LZ18\nsjQ5eeS+Wk3at6+3d9S9PJ/tHREx2uk4au4AKmfr1uQOupXZWem22wb7fBLJHUAF7d6dlEZaOXBA\n2rNnsM8nkdwBVNDq1UnNu5Vly6TTTx/s80kkdwAVNDYmDc3TTjI0lOwf5PNJKZO77Sdtf8/2TttH\nPAW1fZ7t5+v7d9q+tvehAkBvLF6cdKnUatLwsGQnr7Vasr3X7YlZn0/qrhXyLRHxXJv9346IS442\nIADIwpo10t69ycPOPXuS0kg/+86zPh997gAqa8kSacOGcp4vbc09JN1le4ftTfMc8wbbD9m+0/ar\nexQfAGAB0t65vykinrH9Ukl32348Ir7VtP8BSa+IiCnbb5X0VUlnzP2S+h+GTZJ02mmnHWXoAID5\npLpzj4hn6q/PStoq6dw5+38WEVP193dIWmR7eYvv2
 RIRoxExOjLScSERAMACdUzutpfZPqHxXtJa\nSY/MOebltl1/f279e/f3PlwAQBppyjIvk7S1nruHJN0UEV+3/X5JiogbJF0m6Srbs5KmJa2PvCat\nAQB0Tu4RsUfS2S2239D0/npJ1/c2NADAQjFCFQBKiOQOACVEcgeAEiK5A0AJkdwBoIRI7gBQQiR3\nACghkjsAlBDJHQBKiOQOACXEYh0ASm16Oln9aPfuZKHqfq5+VCQkdwCltX27tHatNDsrHTggLVsm\nbd6crFu6Zk3e0fUXyR1AKU1PJ4l9cvLQtqmp5HXtWmnfvnLfwVNzB1BKW7cmd+ytzM5Kt92WbTxZ\nI7kDKKXdu5NSTCsHDkh79mQbT9ZI7gBKafXqpMbeyrJl0umnZxtP1kjuAEppbEwamuep4tBQsr/M\nSO4ASmnx4qQrplaThoclO3mt1ZLtZX6YKtEtA6DE1qyR9u5NHq7u2ZOUYuhzB4ASWLJE2rAh7yiy\nR1kGAEqIO3cAR62qQ/yLjOQO4KhUeYh/kaUqy9h+0vb3bO+0Pd5iv23/te1dth+2/brehwqgaJqH\n+E9NSRHJ6+Rksn1mJu8Iq6ubmvtbIuK1ETHaYt/vSjqj/rNJ0t/1IjgAxVb1If5F1qsHqpdK+lIk\n7pNUs72iR98NoKCqPsS/yNIm95B0l+0dtje12H+KpKeaPj9d3wagxKo+xL/I0ib3N0XE65SUXzbb\nfvNCTmZ7k+1x2+MTExML+QoABVL1If5Fliq5R8Qz9ddnJW2VdO6cQ56RtLLp86n1bXO/Z0tEjEbE\n6MjIyMIiBlAYVR/iX2QdWyFtL5N0TES8UH+/VtJ1cw7bJulq2zdL+i1Jz0fEvp5HC6BwqjzEv8jS\n9Lm/TNJW243jb4qIr9t+vyRFxA2S7pD0Vkm7JL0o6Q/6Ey6AIqrqEP8i65jcI2KPpLNbbL+h6X1I\n2tzb0AAAC8XcMgBQQiR3ACgh
 5pYBMFCYpCwdkjuAgcEkZemR3AEMhOZJyhqmppLXtWulffu4g29G\nzR3AQGCSsu6Q3AEUXqPO3rhTn4tJyo5EWQZAoTXq7O3mhmeSsiOR3AEUVqs6eytMUnYkkjuAwmpX\nZ5ek449Ppj5gkrIjUXMHUFjtFgORpLe9LemSoQ3ySCR3AIXVbjGQ4WHp7W/njn0+JHcAhZV2MZDp\naemmm6RPfjJ5ZWFuau4ACqyxGMjcUalDQ4fq7IxabY3kDqDQ2i0GwqjV+ZHcARTefIuBpBm1WtVF\nREjuQAYaIywff1zav19avlw666zizGjYzUyLRZqVsV03TdVHrZLcgT5r1IQPHkwSY8PSpcWoDXdT\nsy5afbvRTdNqWoKqj1p1skJe9kZHR2N8fDyXcwNZmZ6WTj65/QjLWi2/2nC7+ObG1c2xWZmZkVas\nKFZM/WZ7R0SMdjqOVkigjzqNsJTyndGwm5kWizgrY6ObplZL+t7t5LVWY9QqZRmgjzqNsJTyrQ13\nU7Muan27XTdNlZHcgT5qVxNuyLM23E3Nusj17fm6aaqMmjvQR+1qwg151oa7qVlXsb5dRD2vuds+\n1vaDtm9vsW+j7QnbO+s/7+02YKCMmmvCS5Ycvm/p0vxrw93UrKlvD5ZuyjIfkvSYpJfMs/+WiLj6\n6EMCyqW5JvzEE9Jzz0kjI9KZZxajNtxNzZr69uBIldxtnyrpYkmfkvThvkYElFDRa8LdxFf0fxck\n0pZl/lLSRyX9ss0x77D9sO1bba88+tAAAAvVMbnbvkTSsxGxo81h/y5pVUT8hqS7JX1xnu/aZHvc\n9vjExMSCAgYAdJbmzv2NktbZflLSzZLOt/3l5gMiYn9EHKx//AdJv9nqiyJiS0SMRsToyMjIUYQN\nAGinY809Iq6RdI0k2T5P0h9HxBXNx9heERH76h/XKXnwCuAoFGmCLgyeBQ9isn2dpPGI2Cbpg7bX\nSZqV9BN
 JG3sTHlBNRZugC4OHQUyolKLcDbeLo4gTdKE40g5iYvoBVEZR7oY7xTHIC1AU5Y8nSO6o\niKIsx5YmjqJO0NVJUf54IsGUv6iEokxXmyaOxgRdreQ9Qdd8mv9oTU1JEcnr5GSyfWYm7wirh+SO\nSijK3XCaOMbGpKF5/p96aCjZXzRF+eOJQ0juqISi3A2niWMQJ+gqyh9PHELNHZUwNpbUf1vJ8m44\nbRxHM0FXHg81izzXe1XRConKaPXAb2ioGN0yvYojr39H5nrPTtpWSJI7KqVxV5v3dLX9iCPv/vii\n/PEsO/rcgRaKMl3t0cbRqvSSd388c70XC8kdGDDz9ZNffnn+DzWL8scTJHdgoLQbBHXjjTzUxCG0\nQgIDpF3pxZZ+Oc9yOkXtj0f/kNyBAdKun/zFF6V3vWuw+uPRP5RlgAHSqZ/8zW+WPv95HmqCVkhg\noNBPjrStkJRlgAEyiFMTIB+UZYABQz850iC5AwOIfnJ0QlkGAEqI5A4AJURyB4ASIrkDQAmR3AGg\nhEjuAFBCqZO77WNtP2j79hb7jrd9i+1dtu+3vaqXQQIAutNNn/uHJD0m6SUt9l0p6acR8Urb6yV9\nRtLlPYgPQAp5rJuKYkuV3G2fKuliSZ+S9OEWh1wq6eP197dKut62I6+Ja4AKmW/xDpa3q7a0ZZm/\nlPRRSfPMFq1TJD0lSRExK+l5SSfNPcj2JtvjtscnJiYWEC6AZs2Ld0xNSRHJ6+Rksn1mJu8IkZeO\nyd32JZKejYgdR3uyiNgSEaMRMToyMnK0XwdUXpp1U1FNae7c3yhpne0nJd0s6XzbX55zzDOSVkqS\n7SFJJ0ra38M4AbTQbvGOrNZNRTF1TO4RcU1EnBoRqyStl3RPRFwx57Btkt5Tf39Z/Rjq7UCfNRbv\naIV1U6ttwX3utq+zva7+8QuSTrK9S8kD14/1IjgA7Y2NJeujtsK6qdXW1ZS/EfFNSd+s
 v7+2afuM\npHf2MjAAnTUW75jbLTM0xOIdVcd87sCAY/EOtEJyB0qAxTswF8kdfcGISSBfJHf0HCMmgfyR3NFT\nzSMmG6amkte1a6V9+7iDB7LAlL/oKUZMAsVAckdPMWISKAaSO3qKEZNAMZDc0VOMmASKgQeqJZN3\nCyIjJoFiILmXSFFaEBkxCeSP5F4SRWtBZMQkkC+S+wBrLsH86EfSL37R+rhGCyLJFqgOkvuAmluC\nWbRI+vnPWx9LCyJQPST3AdSqBDNfYpdoQQSqiFbIAdRuFGgrtCAC1cOd+wBqNwpUko47Lqm/04II\nVBfJfQA1RoE2umGaDQ9L7363tGIFLYhAlTmvdaxHR0djfHw8l3MPupmZJHk319wbajVmXgTKzPaO\niBjtdBx37gOIUaDdyXvULpAHkvuAYhRoOkUZtQtkjeQ+wBgF2l7RRu0CWaIVEqXFwiGoso7J3fZi\n29+1/ZDtR21/osUxG21P2N5Z/3lvf8IF0mPhEFRZmrLMQUnnR8SU7UWSvmP7zoi4b85xt0TE1b0P\nEViYdi2jjNpF2XW8c49E4z+PRfWffPongS6wcAiqLFXN3faxtndKelbS3RFxf4vD3mH7Ydu32l45\nz/dssj1ue3xiYuIowgY6a7SM1mrJ4C47ea3VaBlF+XU1iMl2TdJWSR+IiEeatp8kaSoiDtr+Q0mX\nR8T57b6rioOYpqelW26Rvva15PPFF0vr15Nk+q3R507LKMog7SCmrkeo2r5W0osR8dl59h8r6ScR\ncWK776lact++XbrgAumFFw7fPjws3XMPPdcA0kmb3NN0y4zU79hle4mkCyU9PueYFU0f10l6rLtw\ny63Rbz03sUvJw74LL0ymFACAXklTc18h6V7bD0varqTmfrvt62yvqx/zwXqb5EOSPihpY3/CHUxb\nt7ZP3jMz9FwD6K2OrZAR8bCkc1psv7bp/TWSrultaOWxe3f75H7
 wID3XAHqLEaoZWL26/QO844+n\n5xpAb5HcM9CpO2PxYnquAfQWyT0DjX7rE044ct/wsHT33bTmAegtZoXMyJo10o9/TJ87gGyQ3JXd\nYg5LlkgbNyY/ANBPlU/uLOYAoIwqndxZzAFAWVX6gSqLOQAoq0ondxZzAFBWlS7LZL2YQ1YPbgGg\n61khe6UIs0LOzEgrVhxec2+o1Xpbc2/14HZoiAe3ALrTs1khyyyrxRyaH9xOTUkRyevkZLKdGSEB\n9FqlyzJScte8d29/F3NI8+B2w4benQ8AKp/cpWRwUT+TKw9uAWSt0mWZrDQe3LbSjwe3AEByz8DY\nWPLwtJWhIWaEBNB7JPcMZPXgFgAaqLlnJIsHtwDQQHLPUL8f3AJAA2UZACghkjsAlBDJHQBKiOQO\nACXUMbnbXmz7u7Yfsv2o7U+0OOZ427fY3mX7ftur+hEsACCdNHfuByWdHxFnS3qtpItsv37OMVdK\n+mlEvFLS5yV9prdhAgC60TG5R6Ix4/mi+s/ceYIvlfTF+vtbJV1g2z2LEgDQlVQ1d9vH2t4p6VlJ\nd0fE/XMOOUXSU5IUEbOSnpd0Ui8DBQCklyq5R8T/RsRrJZ0q6Vzbr1nIyWxvsj1ue3xiYmIhXwEA\nSKGrbpmImJR0r6SL5ux6RtJKSbI9JOlESftb/PNbImI0IkZHRkYWFjEAoKM03TIjtmv190skXSjp\n8TmHbZP0nvr7yyTdE3mt3wcASDW3zApJX7R9rJI/Bl+JiNttXydpPCK2SfqCpBtt75L0E0nr+xYx\nAKCjjsk9Ih6WdE6L7dc2vZ+R9M7ehlY+09PJrJC7dycLeDArJIB+YVbIjGzfniyGPTubLK23bJm0\neXMyn/uaNXlHB6BsSO4ZmJ5OEvvk5KFtU/WRA2vXSvv2cQcPoLeYWyYDW7cmd+ytzM5Kt92WbTwA\nyo/knoHdu5NSTCsHDiQrMwFAL5HcM7B6dV
 Jjb2XZsmTJPQDoJZJ7BsbGpKF5nm4MDSX7AaCXSO4Z\nWLw46Yqp1aThYclOXmu1ZDsPUwH0Gt0yGVmzRtq7N3m4umdPUoqhzx1Av5DcM7RkibRhQ95RAKgC\nyjIAUEIkdwAoIZI7AJQQyR0ASojkDgAlRHIHgBIaqFZI5kMHgHQGJrkzHzoApDcQyZ350AGgOwNR\nc2c+dADozkDcuXeaD/2JJ6SbbqIWDwANA5HcG/OhN0oxzZYskT77WemYY6jFA0DDQJRl2s2HPj0t\nvfhikvgjktfJyaQWPzOTbZwAUBQDkdznmw996VLpuONa/zMHD1KLB1BdHcsytldK+pKkl0kKSVsi\n4q/mHHOepH+T9IP6ptsi4rpeBtpqPvRHHpE+/enWx09PJ7V4AKiiNDX3WUkfiYgHbJ8gaYftuyPi\n+3OO+3ZEXNL7EA+ZOx/65s3tj3/uuX5GAwDF1bEsExH7IuKB+vsXJD0m6ZR+B5bG8uXt94+MZBMH\nABRNVzV326sknSPp/ha732D7Idt32n51D2Lr6Kyzkrp7K0uXSmeemUUUAFA8qZO77WFJ/yrpjyLi\nZ3N2PyDpFRFxtqS/kfTVeb5jk+1x2+MTExMLjfn/jY3N/0D1uOOS/QBQRamSu+1FShL7P0XEET0o\nEfGziJiqv79D0iLbRxRNImJLRIxGxOhID2om83XR1GrJdgYyAaiqNN0ylvQFSY9FxOfmOeblkn4c\nEWH7XCV/NPb3NNJ5tOqiYYQqgKpL0y3zRknvkvQ92zvr2/5U0mmSFBE3SLpM0lW2ZyVNS1ofEdGH\neFua20UDAFXXMblHxHckucMx10u6vldBAQCOzkCMUAUAdIfkDgAlRHIHgBJyhs89Dz+xPSHph7mc\nvFiWS2KihEO4HodwLQ7H9Ui8IiI69pLnltyRsD0eEaN5x1EUXI9DuBaH43p0h7IMAJQQyR0ASojk\nnr8teQdQMFyPQ7gWh
 +N6dIGaOwCUEHfuAFBCJPcM2L7I9hO2d9n+WIv9H7b9fdsP2/4P26/II86s\ndLoeTce9w3bYLnWHRJrrYfv36r8jj9q+KesYs5Tiv5fTbN9r+8H6fzNvzSPOwosIfvr4I+lYSbsl\nnS7pOEkPSXrVnGPeImlp/f1Vkm7JO+48r0f9uBMkfUvSfZJG844759+PMyQ9KOlX6p9fmnfcOV+P\nLZKuqr9/laQn8467iD/cufffuZJ2RcSeiPi5pJslXdp8QETcGxEv1j/eJ+nUjGPMUsfrUfdJSZ+R\nNJNlcDlIcz3eJ+lvI+KnkhQRz2YcY5bSXI+Q9JL6+xMl7c0wvoFBcu+/UyQ91fT5abVfg/ZKSXf2\nNaJ8dbwetl8naWVEfC3LwHKS5vfjTEln2v5P2/fZviiz6LKX5np8XNIVtp+WdIekD2QT2mBJM587\nMmL7Ckmjkn4771jyYvsYSZ+TtDHnUIpkSElp5jwl/1f3Ldu/HhGTuUaVn9+X9I8R8Re23yDpRtuv\niYhf5h1YkXDn3n/PSFrZ9PnU+rbD2P4dSX8maV1EHMwotjx0uh4nSHqNpG/aflLS6yVtK/FD1TS/\nH09L2hYRv4iIH0j6byXJvozSXI8rJX1FkiLivyQtVjLvDJqQ3Ptvu6QzbP+q7eMkrZe0rfkA2+dI\n+nslib3M9VSpw/WIiOcjYnlErIqIVUqeQayLiPF8wu27jr8fShacP0+S6msTnylpT5ZBZijN9fgf\nSRdIku1fU5LcJzKNcgCQ3PssImYlXS3pG5Iek/SViHjU9nW219UP+3NJw5L+xfZO23N/mUsj5fWo\njJTX4xuS9tv+vqR7Jf1JRGSyRnHWUl6Pj0h6n+2HJP2zpI1Rb53BIYxQBYAS4s4dAEqI5A4AJURy\nB4ASIrkDQAmR3AGghEjuAFBCJHcAKCGSOwCU0P8BW5yeWIjH3fgAAAAASUVORK5CYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f3c7ec4bcd0>"
+       "<matplotlib.figure.Figure at 0x7fede8c0f438>"
       ]
      },
      "metadata": {},
@@ -149,19 +148,19 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 5,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
     "def plot(idx, x, y):\n",
     "    global gx, gy, axes\n",
     "    # print the ground truth line\n",
-    "    axes[idx/5, idx%5].plot(gx, gy, label='y=f(x)')     \n",
+    "    axes[idx//5, idx%5].plot(gx, gy, label='y=f(x)')     \n",
     "    # print the learned line\n",
-    "    axes[idx/5, idx%5].plot(x, y, label='y=kx+b')\n",
-    "    axes[idx/5, idx%5].legend(loc='best')\n",
+    "    axes[idx//5, idx%5].plot(x, y, label='y=kx+b')\n",
+    "    axes[idx//5, idx%5].legend(loc='best')\n",
     "\n",
     "# set hyper-parameters\n",
     "max_iter = 15\n",
@@ -187,37 +186,37 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 6,
    "metadata": {
-    "collapsed": false
+    "scrolled": false
    },
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "loss at iter 0 = 8.897375\n",
-      "loss at iter 1 = 7.806258\n",
-      "loss at iter 2 = 6.850243\n",
-      "loss at iter 3 = 6.012600\n",
-      "loss at iter 4 = 5.278670\n",
-      "loss at iter 5 = 4.635614\n",
-      "loss at iter 6 = 4.072176\n",
-      "loss at iter 7 = 3.578499\n",
-      "loss at iter 8 = 3.145944\n",
-      "loss at iter 9 = 2.766943\n",
-      "loss at iter 10 = 2.434863\n",
-      "loss at iter 11 = 2.143896\n",
-      "loss at iter 12 = 1.888950\n",
-      "loss at iter 13 = 1.665564\n",
-      "loss at iter 14 = 1.469831\n"
+      "loss at iter 0 = 9.660777\n",
+      "loss at iter 1 = 8.484187\n",
+      "loss at iter 2 = 7.452227\n",
+      "loss at iter 3 = 6.547118\n",
+      "loss at iter 4 = 5.753264\n",
+      "loss at iter 5 = 5.056990\n",
+      "loss at iter 6 = 4.446301\n",
+      "loss at iter 7 = 3.910676\n",
+      "loss at iter 8 = 3.440886\n",
+      "loss at iter 9 = 3.028838\n",
+      "loss at iter 10 = 2.667435\n",
+      "loss at iter 11 = 2.350451\n",
+      "loss at iter 12 = 2.072425\n",
+      "loss at iter 13 = 1.828568\n",
+      "loss at iter 14 = 1.614680\n"
      ]
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAArwAAAHVCAYAAAATqShMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3XlcVNX7wPHPFUEWFwTFDRF3QwXctyy1PS3TzFyq7zez\nrLTE8mv1s6zMNsv2faVUxL3S1DYttUVTFnEXFRVBdpCdYeb8/kBLZIABZud5v168ksPM3OfOPN15\n7j3nnqMppRBCCCGEEMJZNbB1AEIIIYQQQliSFLxCCCGEEMKpScErhBBCCCGcmhS8QgghhBDCqUnB\nK4QQQgghnJoUvEIIIYQQwqlJwSuEEEIIIZyaFLxCCCGEEMKpScErhBBCCCGcWkNLvGiLFi1UYGCg\nJV5aWNnevXvTlVItLfHakifORXJFmELyRJhKckWYwtQ8sUjBGxgYyJ49eyzx0sLKNE07ZanXljxx\nLpIrwhSSJ8JUkivCFKbmiQxpEEIIIYQQTs2kK7yapiUAuYAeKFVK9bdkUMJxSa4IU0ieCFNJrghT\nSJ6I6tRkSMNIpVS6xSIRNpWRV0xj94Y0auhijpeTXHFi53KKaN3M3RwvJXnixHIKdLg21PB0M8vI\nOckVJybHFGGKvOJSDErR1N21Vs+3yBhe4Vh+OpjCU+v2MbF/e+bd2MOmseh0OhITEykqKrJpHI7C\n3d0df39/XF1rdwCoifziUp7fcIDNcefYMucq2nl7WHybVZFcMZ018wRg76lMHl0Rw1XdWvLy+N5W\n2WZlJE9qxpq5otMbeP3HI4T/nsC3s4bRo3VTi2+zyngkV0xm7WNKfGouM5bupYtfYz6+u3YX700t\neBXws6ZpeuBjpdQnlz9A07QHgAcAAgICahWMsK7cIh0vbDzIqj2JXNGmKbeGtjXHy1aZK9XlSWJi\nIk2aNCEwMBBN08wRj9NSSpGRkUFiYiIdO3a06LZiz
 2QzOzKaU5kFPDyiM35NGtX1Jet8TJFcMY01\n80RvUHz023He+Oko7bw9uHNAe3O8rBxTrMSauZKcU8gjEdHsOZXF1EEBBPp61fUl5ZhiJdbME4Dv\n9yUzb00sHm4u/GdoYK1fx9SC90ql1FlN0/yAnzRNO6yU2n7pAy4k1ycA/fv3V7WOSFjFXycymLs6\nlqTsQh4e0Zmwa7vh1tAs9zBWmSvV5UlRUZEcbEykaRq+vr6kpaVZbBsXC5g3fzqKX5NGRN4/mEGd\nfM3x0nU+pkiumMYaeQKQmlvEYytj2RmfzpjgNrw0vnetux4vI8cUK7FWrmw/mkbYyhiKdHrenhTK\n2NB25nhZOaZYibXyRKc38Ormw3y28yR9A7x5f2pf2jSrfc+iSQWvUurshf+mapq2HhgIbK/6WcIe\nFen0LPnxCJ/tPEkHH09WPziUfh2am+31zZErcrAxnSXfq7PZhcyJjGF3Qiajg9vw0m29aeZpnu4r\ncx1TJFdMY+n36bejaTy+Koa84lJeGd+bOwe0N9s25ZhiXZZ8r/QGxVs/H+W9bfF082vC+1P70sWv\nsVleW44p1mXp9yk1t4hZEdHsPpnJf4Z0YP7ooDpflKu24NU0zQtooJTKvfDv64GFddqqsIn9Z3N4\nbFUMR1PymDoogPmjrzDXDSWA5Ioz+S42ifnr4zAYFEvuCGF833ZmO8BJnjiPi2MwP/7tBN1bNWHF\n/YPp2qqJ2V5fcsV5pOYW8eiKaP46kcnE/v48f2svPNzMcpO05ImT+Tshk5nLozhfpOOtO0O5rY9Z\negBMmoe3FbBT07RYYDfwvVJqi1m2LqyiVG/g3V+Ocdv7v5NdoCP83gG8OK63WYvdC+ptruzYsYOe\nPXsSGhpKYWEhycnJjBkzpsrnbNy4kQULFlgpQtPkFul4bGUMj66IpqtfYzbPvorb+/mb+2y+3uYJ\nOE+unM4oYMJHf/LxbyeYMiiA
 b2cNM2uxe0G9zRVnyROAP46nc/PbO4k5k81rE4JZPCHEbMXuBfU2\nT8B5ckUpxRc7TzL5k7/wdHPhm5nDzFbs/rMBc//069dPCftwPDVXjX1vp+rwxEY1KyJKZeUX1+j5\nwB5lgRxRleTJwYMHa76TdmDGjBlq6dKl//w+d+5c9c0331T5HIPBoEJDQ1V+fn6dtm2u92xPQoa6\n8tVfVMcnN6o3fjyidKX6Gj1fcsU0tsoVc75fG2LPql4Ltqhez25R3+9LqtFzJU9M4wzHFL3eoN7+\n+ajq+ORGNer1bepw8vkaPV9yxTTOcEzJK9KpWRFRqsMTG9X0r/5WOYUlJj/X1DyRacmclMGgWLbr\nFC9tOkSjhi68O7kPt4SYZRYGq3l+wwEOJp0362sGtW3Ks7f0rPTvCxYswMfHh7CwMADmz5+Pn58f\ns2fPrvQ5n332GatWreKHH35g8+bNLF++nLVr17Jo0SIA3nzzTeLi4vjiiy+Ii4tj8uTJ7N69G09P\nT0aMGMHGjRuZOHGiWfezJkr1Bt7dGs+7W4/R1tuD1Q8OoV8HH5vFUxuSK9ZRWKJn4cYDrNh9hj4B\n3rwzqQ/tfTxtFk9NSZ5YT0ZeMWErY9hxLJ2xoW15aVxvvBo5TskhuWI9x9PyeHDpXo6n5fG/G7rz\n0NWdadDA/GOEHSf7hMmScwqZt2YfO46lc1W3lrw2IZhWTc0yqbfTmzZtGuPHjycsLAyDwUBkZCRb\nt24lNDTU6OMjIiKYPn06O3fuZMyYMUyYMIGTJ0/SvHlzGjUqm7pr9uzZjBgxgvXr1/Piiy/y8ccf\n4+lZViT079+fHTt22OyAczqjgLCV0USdzmZcn3YsHNuTJua5s97p1bdcOXzuPI9ERBOflsdDIzrz\n2HXdcHWR1emrU9/yBMrGYD4SEU1mQQkvjevN5IHmu4nRmdXHXNmyP5m5q/fh1rABX08bxJVdW1hs\nW1LwOhG
 lFN/GJLHg2/3o9IoXbuvFXYMCHPZAU9WZsKUEBgbi6+tLdHQ0KSkp9OnThw4dOhATE2Py\nayQnJ9OyZct/fm/QoAHh4eEEBwczY8YMhg0b9s/f/Pz8SEpKMus+mEIpxbqosyz4dj8NGmjmnBrI\nJiRXLEcpRcTu0yzccJAm7q58PW0gw7u2rP6JdkjyxLIMBsWnO06w+Icj+Df3YN1DQ+nVrplNYqkr\nyRXLKtUbeO2HI3y8/QQh7b35cGpf2lp4MSMpeJ1EZn4Jz3yzn+/jkukb4M0bE0MJbFHnibzrpenT\npxMeHs65c+eYNm0aubm5DB8+3OhjIyIiCAoKKtfm4eFRYaWeY8eO0bhx4woHl6KiIjw8rLtiWU6B\njvnfxLFxXzIDA314484Q/Js7Tre0PXH6XCnU8dS6fWyKO8fwri14Y2IoLeu+6Ei94+x5ApBdUMLc\n1bH8fCiVm3q15tUJweaah7leqQ+5kp5XzCMR0fx5IoO7BgfwzJggGjU0602MRknB6wS2HU5l3tp9\nZBeU8L8buvPg1Z1xscD4l/pi3LhxLFiwAJ1OR0REBC4uLjU6w+7WrRsJCQn//J6Tk8Ojjz7K9u3b\nmTVrFmvWrGHChAkAHD16lF69epl7Fyq160QGc1bGkJpbLLliBs6cK1Gns3gkIpqU80U8cWMPZlzV\nySLj6uoDZ84TgJgz2cxcHkVqbhHP3RLEf4bK4g215ey5svdUFg8v30t2gY4ld4Rwez9/q21bCl4H\nll9cyqLvD7Fi92l6tG7CV/cOJKitbdcidwZubm6MHDkSb29vXFxqftbp5eVF586diY+Pp0uXLsyZ\nM4eZM2fSrVs3Pv/8c0aOHMlVV12Fn58f27Zt4+WXX7bAXpSn0xt46+ejfPDrcQJ9vVjz0FBC23tb\nfLvOzhlzxWBQfLz9BK//eIQ2zdxZ9eAQ+gaYb3Ga+sgZ8wTKhrt8+XsCL28+hF8Td9Y8
 OJQQOa7U\niTPnytK/TvHCxoO0aebBuocH0LOtlYe7mDKVQ01/ZFoyy9t9MkMNf3WrCnxyo3rp+4OqSFdqke1Q\nD6eF0ev1KiQkRB09erTWr7Fu3To1f/78Kh9z7tw5NWrUqFpv46Lq3rPjqbnqlnd3qA5PbFTzVseq\nvCJdnbdpjORK7VgrV0x5v1LPF6m7PvtLdXhio3po2R6VXWD61ECmkjypHXs6piilVE5hiXpw6R7V\n4YmN6r7w3So7X3LFHBwpV0x9v/KLdWr2irIpx+790vy5YmqeyBVeB1NcqueNn47yyfYT+Df3YOUD\nQxjY0bGmkLJnBw8eZMyYMYwbN46uXbvW+nXGjRtHRkZGlY85ffo0S5YsqfU2qqOUYuXfZ3h+w0Hc\nGjbgw6l9ual3G4ttr75xplwB2HEsjTkrY8kt0smd9WbkbHkCZat2zoyIIjGrkP+7uQf3D+8kuWIG\nzpgrJ9PzeWjZXo6k5PL4dd2YObKLzYZGScHrQA4mneexVTEcPpfL5IHtmT86iMYONK+hIwgKCuLE\niRNmea3p06dX+fcBAwaYZTvGZOWX8NS6OLYcOMfQzr4smRhCm2bWvznBmTlLruj0Bt746Sgf/nqc\nrn6NWT59EN1bm33FtHrLWfIE/p2x4/kNB/HxdGPlA4PpHygXXMzFmXIF4McD53h8VSwuLhpf3TuQ\nq7rZdnYXqZYcgN6g+Hj7cd786Sjenm588d/+jOrRytZhCTv1e3w6j62KITO/hKduKrv6IjcbCWPO\nZBbwaGQ00aezmTwwgAVjgsy95KtwEvnFpfzf+ji+jUni6m4tefPOUHy83GwdlrBDpXoDSy6cRAf7\nN+ODqX3tYiYgKXjtXEJ6Po+vjmXvqSxG927Dott60VwOMsKI4lI9S34sG+7SuaUXn/9ngMPOgSks\nb1NcMk+s3QcK3pvShzHBjrUSo7Cew+fO8/DyKBLS85l7fTceHmG
 7bmlh3zLyink0Mprf4zOYPDCA\nZ28Jwt3VPk6ipeC1U0oplu86zYvfH8LVpWxhgFtD2so4KWFUfGouj66I4WDyeaYOCuDp0XKlThhX\npNOzcONBInadJrS9N+9OdqzlgYV1rdpzhgXf7qeJuyvLpg9iaGfLrYQlHFv06SweXh5FRn4JiycE\nM7F/e1uHVI4UvHYo5XwR89bs47ejaQzv2oLFE4Jl/KUwSilFXnEpd72zE69GDfn0nv5cFyTDXYRx\nR1NyeSQimiMpucy4uhNzr+8uywMLowpL9Dzz7X7W7E1kaGdf3poUil8TWaJeVKSUYtmu0yzccIBW\nTd3tdoU9OdLZmQ2xSVz/5nZ2nczg+Vt78tW9A6XYdQCBgYGkp6db9fV0egOnMgrILtAxsKMPW2YP\nl2LXAdgiV5RS5BeXcut7O8nIL+araQN56qYrpNi1Y7bIk4t0egNj39/J2qhEHh3VhaX3DZJi147Z\nMlcKS/Q8vjqWZ77Zz5VdWrDxkSvtstgFucJrN7ILSnjm2wNsiE0itL03b0wMoVPLxrYOS1hYeHg4\nCQkJPPfcczV6Xm6RjjOZheiVwtvDla/u7SNj6pxcbXNFbzBwNquQrAId/TuULSUtxYvzqm2eXJRV\nUEJabjHpeSV2cWe9sJy65kqp3sC4D37nSEouc67txiOj7Htst8kFr6ZpLsAe4KxSaozlQqp/fjua\nxrw1sWTklfD4dd14aERnGjrolRez5snmJ+FcnFni+kfr3nDTK5X+ecGCBfj4+BAWFgbA/Pnz8fPz\nY/bs2Sa9fGFhIePHj2f8+PGEhoZy3333sXv3bvR6PQMHDmTlypUmL+W4ePFiNm/ejIeHBxEREXTp\n0gWDQXHufBHpecW4u7rQsbkXCecb2vVBxiokVyrkCkBBSSmnMwvQlSqaeTTk62n1/MRI8sRonkDZ\nCntJOYVk5pfg6tKATY8Op3WzenxiJLlSaa
 4AnC/UkZpbTHJOEV/8dwAju/uZ9Lq2VJMrvLOBQ4Cs\nXWsmBSWlvLTpEMv+Ok1Xv8bOcle9Q+fJtGnTGD9+PGFhYRgMBiIjI9m6dSuhoaFGHx8REUFQUBAA\neXl5TJo0iXvuuYd77rkHgFtvvZWnn36awsJC7rrrrhqtW96sWTPi4uL4+uuvCQsLY/X6bzmTWUCR\nTk+Lxo1o3dTdoYsXRz+Jtudc2bBhA+l5xZzLKcbVRaNTSy9O57o6dL44KnvOk40bNwJQrNNzOrOA\nQp2elk0a0bCxW/0udm3EEXJFKUXK+WJSc4to2EBj4yNXOs5Nr6Ysxwb4A78Ao4CN1T1elhau3p6E\nTHX14rKlgV/YcEAVllhmaeC6ogZLO5ojT+xhacdrr71WRUVFqc2bN6vbb7/dpOd06NBBBQcHq2XL\nlpVrLy4uVsHBwWrgwIGqtLTsM05PT1chISEqJCREtW/fXrVq1eqf3/ft2/fP6x0/fvyf12je3Eft\nS8xWB87mqPOF5ZdltIf3TKmaLwMKPAZESK6UMUeulJSUKB8fH3UiLU/FnslSCel5SleqV0rZx/ul\nVK3yxAWIljwpY848UUqp7PxitT8xW+0/m61yLiwlbQ/vmVL1c2lhe84VXaleHU/NVbFnstTpjHx1\n4MABc+12nZiaJ6Ze4X0LmAdUuvyOpmkPAA8ABAQE1KDkrl9KSg28/UvZhMxtmnmw4v7BDO7ka+uw\nzKXaPHEE06dPJzw8nHPnzjFt2jRyc3MZPny40cdeeoY9bNgwtmzZwpQpU/6ZPi4jI4O8vDx0Oh1F\nRUV4eXnh6+tLTEwMUPUYKk3T0OkNJGQUoIAmjRri39zDYYe7XErTNH9gNPAiZYWvQ7KnXAHIK9Jh\nUGWLBLTz9sDHy80ZpjJ06F4jsL88ufjvpOxC0vOK8XRrSICPB24NHXsqQ0fvNQL7zZWCklJOZxSg\nMyj8m3vg49WIQymOd
 Wyp9ptT07QxQKpSam9Vj1NKfaKU6q+U6t+ypQxyN+bwufOMff933t92nNv7\n+rMlbLjTFLum5ommaQ9omrZH07Q9aWlpVoquZsaNG8eWLVv4+++/ueGGG2jSpAkxMTFGfy4ebAAW\nLlxI8+bNmTlz5j9tM2bM4IUXXmDq1Kk88cQTNYrjq2URHEvJY+3qVQwcNJgOvp5OUexecPHkyFDZ\nAyRXTBcZGcm5nEI+/HIpof0H0tmvMb6NGzl8sXvJidFnto6lLuwlT1auXAnA8ogVBPcdQHpeMS0a\nN6JTSy+HL3YvuHhy5LDsLVciIyPpN2AQx9PyAejc0gsfr0Zm2FPrM+UK7zDgVk3Tbgbcgaaapi1T\nSt1l2dCch96g+GzHCZb8eJSmHk47V6pJeaKU+gT4BKB///7K+mFWz83NjZEjR+Lt7Y2LS82+BN5+\n+22mTZvGvHnz6NWrF66urkyZMgW9Xs/QoUPZunUro0aNqvI1DAaF3qA4lZzK+GuH4uXpwcrIFQ5f\nvFx06cmRpmkjKnuc5Er1uXLRyaRUrhrcHw93d1atjMTDTlY2MgOn6F20lzzJysqiV+/e4OLKa+9/\nTgdfT5p5OMfKnc7Sa2RPuRIcHIzm4sqL73yKl5sLAT4OftHFlHEPF3+AEcgY3ho5nZGv7vjwD9Xh\niY3qga//Vum5RbYOqUaoxRiquuSJPYyh0uv1KiQkRB09etTq2y4o1qnDyedV7JkslZRVoPQGQ7XP\nsYf3TCnTcwV4GUgEEoBzQAGwrKrnSK4Yl11QrPafzVb7E7NVVn5xlY+1h/dLqRrlyRjgAyXHFPPE\nYDCopOwCFXsmSx09d14V6Sq/b8Qe3jOlavb9A6wB+lWVK5SdGO0B9gQEBFTYnj3stz3kilJKFetK\n1dFzZd9FydmFymDku8ge3i+lTM8TBy7V7ZtSisjdp7nxre0cSj7PkjtC+Oiufvg2dsyugPri4MGD\n
 dOnShWuuuYauXbtabbtKKdJyi4hPy8egFB1beNHG24MGTnJV91JKqaeUUv5KqUBgErBVOWCPka1y\nBcp6Ac5mFXAqowC3hg3o0qox3p7OcaXuEhd7jRKASGCUpmnLbBtSzdkyTy4qKTVwMi2ftNxifL3c\n6NyyMY2cYwgD4DxDL+0hVwDOF+k4lppHid5AoK8XrZu5O0UPY40WnlBK/Qr8apFInEhqbhFPro1j\n6+FUhnTy5fWJIbTzrj+rpTlyngQFBXHixAmrblNXauBMVgF5xaU083Clnbdz3Jjm7GyRKwBFF6aQ\n+md6umbuTntiBDwFcGHoy1xHPDGyVZ5cVLZITQEGBQE+ns54YgROMvTS1rmilCIlt5jU80W4u7rQ\nwdfTqU6MZKU1M9sUl8z89XEUlOhZMCaI/w4NlLkva0gp5RRnk6bIKSghMbsQpcC/uQfNPWt2V31Z\nb47jquvJUX3KFaUUWQU6krILaaBpBLbwoqm7q8nPrc/qU55cpNS/86W6u5aNv3Q3YWy3I+aKOU+O\n6mOuQNmqaWeyCskt0tHc04123h5V1i6OmCdS8JpJToGOZ7/bzzcxSQT7N+ONiaF08ZOlgWvK3d2d\njIwMfH19nfqgozcokrMLySwowdPNhfbNPWlUwxuNlFJkZGTg7l4/J4ivL7kCF5cHLiK7sITGjRrS\n3scTVxN7AZwhT+pyYlSf8uQind7A6cwC8otL8fF0o201xctFzpArdVEfcwWgsKSUUxemHDNlOkNH\nzRMpeM1g57F0/rcmltTcYmZf05VZo7qY/GUkyvP39ycxMRF7nYbKHEpKDWQVlFCqVzR2b0hD94ac\nyKjdwdXd3R1/f38zR+gY6kOuQFm+ZOaXoDcomno0pGEjV+LTa/YakifOnycXFev0ZBboUErh7elK\nbm5DjqSY/nxHz5W6nBzVt1yBsjm7swt1uGgaPl5upJ5vQKoJz3PEPJGCtw4KS
 /S8svkQX/15is4t\nvVj30FBC2nvbOiyH5urqSseOHW0dhkXoDYqPfjvOmz8dxa9JI968M5RBTjIPsy04c65A2Y1pX/x+\nkle3HKZl40a8M7kP/QN9bB2Ww3H2PLlIb1C8vy2eN38+QeeWjflgal+6tXLoNYCsrr7kCpTdC/D8\nhgOs2H2GK7u04J3JffDxcsrx3f+QgreWok9n8fiqWE6k53PvsECeuLGHSeOjRP2UmFXAYytj2Z2Q\nyZjgNrw4rjfNPEwbfynqn4y8YuaujmXbkTRu6NmKV28PdtabjYQZpOcVM2dlDDuOpTOuTzsW3dYL\nr0by9S6MO5NZwMPLo4g7m8PMkZ157LruuNSDe43k/4ga0ukNvPPLMd7fFk/rpu5E3D+IoZ1b2Dos\nYce+i01i/vo4lIIld4Qwvm+7ejU+TNTMH/HphK2MIbtQx8KxPbl7cAfJF1Gp3SczeWRFFFkFOl4e\n35tJA9pLvohK/XY0jdmR0ej1ylkXwaqUFLw1cCwllzmrYth/9jzj+7bjuVt7mnyXtKh/cot0PPvt\nAdZFn6VvgDdv3dmHAF9PW4cl7FSp3sDbvxzjvW3xdGzhRfi9Awlq29TWYQk7ZTAoPt5+gtd/PEL7\n5h58+bDki6icwaB4b1s8b/58lO6tmvDRXf0IbOFl67CsSgpeE1wcS7f4hyM0btSQj+7qx429Wts6\nLGHH9p7KJGxlDGezCpl9TVceGdVF5tYVlUrKLmR2ZDR/J2RxRz9/nh/bE083OTwL47LyS3h8dSxb\nD6cyuncbXrm9N03k4ouoRE6BjjmrYth6OJVxfdrx0rjeeLjVvyGYckStxpnMAuaujmXXyUyuvcKP\nl8cH07KJrJYmjCvVG3h3azzvbj1Gu+YerH5wCP06yI1GonI/HDjHvDX7yq7wTgplbGg7W4ck7Fj0\n6SxmRUSTmlskQ15EtQ4k5fDQsiiScwrrfb5IwVsJpRSr
 9yaycMNBABZPCOaOfv71NlFE9U5nFBC2\nMpqo09mM79OO58f2lKsuolJFOj0vbTrE13+eone7Zrw7uU+962IUplNK8cXvCby86RCtm7mz5kGZ\nFUhUbc3eROavj6O5pxsrZwyhb0BzW4dkU1LwGpGWW8xT6+L4+VAKgzr68PodIbT3kbGXwjilFOui\nzvLsdwfQNHhnch9uDWlr67CEHYtPzeORFdEcSj7PfVd2ZN6N3Z1qCU9hXjmFOuatieWHAylcF9SK\n1yeE0MxTTqaFccWlep7fcJCIXacZ0smXd6f0oUVj6ZmWgvcyW/afY/76OHKLS3l69BVMG9ZRlgYW\nlcop1PH0N/vZEJvEwEAf3rgzBP/mcnIkjFNKsWZvIgu+PYC7awO++G9/RvWoP3dJi5qLS8zh4Yi9\nJGcXMf/mK5g+vKP0NIpKnc0u5OFle4lNzOHBqzsz9/pucv/IBVLwXnC+SMdz3x1gXdRZerZtyoo7\nQ2XSblGlXScyeGxVLCnni5h7fTceGtGlXsxlKGonr7iUp9fH8U1MEkM6+fLmnaG0buZYS3MK61FK\nseyvU7yw8RC+jd1YOWOw3A8gqrTzWDqPrIhCp1dyc70RUvACfxxPZ+6qWFJyi3lkVBceGdUVt4Zy\nRiSM0+kNvPXzUT749TgdfDxZ89BQQmUsnajC/rM5zIqI4nRmAXOu7casUXJyJCqXV1zKU+vi2BCb\nxIjuLXljYqjTr4Ilas9gUHz423GW/HiELn6N+eiufnRq2djWYdmdel3wFun0vLrlMF/+nkCnFl6s\neXAIfer5oG5RtZPp+YRFRhObmMPE/v48e0tPWdFIVOrijUavbD5Ei8aNiHxgCAM7ylU6UblDyeeZ\nuTyKhIx8/ndDdx66urMMqxOVyinU8fiqWH4+lMKtIW155fbeMqVhJap9VzRNcwe2A40uPH6NUupZ\nSwdmafsSs5mzMobjafn8Z0gHnrz
 pino5L50wjVKKVXvO8Nx3B3Fr2IAPp/blpt5tbB2WsGOZ+SX8\nb3UsvxxO5bqgViy+PZjmcpVOVEIpxeo9iTzz7X6aebgScf9gBnfytXVYwo4dSj7PQ8v2kphVyIIx\nQdw7LFDGd1fBlNOAYmCUUipP0zRXYKemaZuVUn9ZODaL0OkNvL8tnne3xtOycSOW3jeQ4V1b2jos\nh+esJ0ZQNsn7U+vi2HLgHEM7+7JkYghtmnnYOixhx/48nkHYymiy8nU8d0sQ/xkqX0SicgUlpTzz\nzQHWRiUyrIsvb93ZR+Z7F1VaH53IU+viaOruSuQDg+kfKD1H1am24FVKKSDvwq+uF36UJYOylPjU\nPB5fFUPmOrCoAAAgAElEQVRsYg63hbbl+Vt7ydQu5uNUJ0YX/R6fzmOrYsjML+H/bu7B9Cs7Sfei\nqNSlC48E+nrx+X8G0KtdM1uHJexYfGouDy2LIj4tj9nXdOXRa7rK+G5RqZJSA4u+P8jXf55iYEcf\n3pvSB78mcvOrKUwa6KFpmguwF+gCvK+U2mXkMQ8ADwAEBASYM8Y6MxgUX/2ZwCubD+Pp5sL7U/oy\nOli6o83JmU6MoGwewyU/HuWT7Sfo3FIKF3Ny1t6A5JxCZkfGsPtkJrf39WfhWBnfLar2TfRZnloX\nh6ebC0unDeLKri1sHZKwY8k5hTy8PIro09ncP7wjT9zYQ6YcqwGTjsZKKT0QqmmaN7Be07ReSqn9\nlz3mE+ATgP79+9tNoXM2u5D/rY7lj+MZjOrhxyvje+PXVM6GLMHRT4wuik/N5dEVMRxMPs/UQQE8\nPTpIxnebl9P1Bvx8MIW5a2LRlRp4884QxvXxt3VITsFZT46KdHqe33CAFbvPMLCjD+9O7kMr+V4S\nVfgjPp1HVkRTpNPzwdS+3Cz3kNRYjS4/KKWyNU3bBtwI7K/u8baklGJ99Fme/fYABqV4ZXxv7hzQ\nXsbRWZAjnx
 jBhXkvd51m0caDeDVqyGf39OfaIFkUwNycqTeguFTPy5sOE/5HAr3aNeXdyX3pKMsD\nm5PTnRydTM/n4eVRZTccjejM49fJwgCickopPt5+gsVbDtOpZdmUY138ZMqx2jBlloaWgO5CsesB\nXAe8avHI6iAjr5j56/ez5cA5BgQ2Z8kdoQT4yupX1uJIJ0YXpecV8+Taffx8KJWrurXk9QnB0hNg\nQc7QG3AirWx54ANJ57l3WCBP3tRDlgc2M2c6OQLYuC+JJ9fG0dBF48v/DmBkDz9bh+QUnLUn4HyR\njv+tLltSenRwGxbfHizDpOrAlHeuDfDVhS+oBsAqpdRGy4ZVez8dTOGpdfs4X1jKUzf1YPrwTnID\ngBU44onRRb8eSWXu6n2cL9KxYEwQ/x0aKDemWZij9was3Vs2fVSjhg2kJ8DCTDk5snfFpXpe+v4Q\nX/15ij4B3rw3pS/tvGWmFzNyup6Aoym5PLh0L6cyC3h69BXcd6UsKV1XpszSsA/oY4VY6iS3SMcL\nGw+yak8iV7RpyrLpIfRo3dTWYdUnDnViBGXj6F7ZXNYd3b1VE5beN5Ar2kjOWJOj9QbkF5fyzDf7\nWRd9loEdfXh7UqhMUWdh1Z0c2XtPwJnMAmZGRLEvMYfpV3Zk3o09ZCVPM3O2noBvY87y5No4vBo1\nJGL6IAbJfMxm4RTXxnedyODx1bEkZRfy8IjOhF3bTQ4oVuYoJ0YXHT53ntkrYjiSkst/h5Z1R7u7\nSne0NThqb8D+szk8siKaUxn5Mn2UDVR2cmTPPQE/HjjH3NWxKODju/txQ8/Wtg7JaTnDMKmSUgMv\nbTpE+B8JDAhszvtT+srQOjNy6IK3SKdnyY9H+GznSQJ8PFn94BD6dZDJl0XlDAZF+B8JvLLlME3d\nXfny3gGM7C7j6KzMoXoDlCrLmZc3HcbHy01WwLIiRz050ukNLN5ymE93nKR3u2Z8MLUv7X3
 kPhJL\ncvRhUinni3h4eRR7T2UxbVhHnrq5B65yM6NZOWzBu/9sDo+tiuFoSh5TBwUwf/QVsn60qFJqbhFz\nV+9j+9E0runhx6sTgmnRWFYzsjZH6g3Iyi/hf2v28fOhFK69wo/FE0LwkeWBrcmhTo4AkrILmRUR\nRdTpbO4e3IGnx1whNzNakaMNkwL460QGsyKiKSgp5d3JfbglpK2tQ3JKDlchluoNfPjrcd7+5Rg+\nXm6E3zuAEXKFTlTj54MpzFu7j/ziUl4Y25O7BneQGwBElXadyGB2ZNkqe7JOvW040skRlN0AO2dl\nDCWlBilcrMhRewKUUny24ySvbDlMBx9PIu4fRLdWTWwdltNyqIL3RFoej62KJeZMNreEtOWFsT3x\n9pSrLaJyhSV6Xtx0kGV/nSaoTVPenhRKVzmgiCroDYp3tx7jnV+OEeDjybqHh8oqe6JKpXoDb/58\nlPe3HadH6yZ8MLUvnVrKXKlW5HA9AXnFpcxbE8umuHPc2LM1r90RTBN3V1uH5dQcouBVSrH0r1O8\ntOkQjRq68M7kPtwqZ86iGvvP5jA7MprjafncP7wjc2/oLl2LokrncoqYHRnNrpOZjOvTjhdu60Vj\nmfdSVCHlfBGPrijLmckD2/PsLT3lBlgrc7SegPjUXGYs3UtCRgH/d3MP7h/eSXqPrMDuj+TJOYXM\nW7OPHcfSubpbSxZPCJYlGEWVDAbFZztP8NoPR/DxcmPZfbJGvajeL4dSmLs6luJSA6/fEcKEfrI8\nsKja7/HpzI6MJr9YzxsTQxjfV3JGVG3jviTmrdmHp5sLy+4bxJDOcgNspc7uBe9A8DLPe2S3Ba9S\niu9ik3jmm/3o9IpFt/Vi6qAAOQsSVTqXU8Rjq2L443gGN/RsxSvjg2kuNxmJKhSX6lm85Qif7zzJ\nFW2a8t6UPnSW7mhRhYvDXt7+5RhdWjZmxf19ZaiUqJJOb+CVzYf5fO
 dJ+gZ488HUfrRuJhfvjDq3\nHz4aVvbvIbPghhfN8rJ2WfBm5Zfw9Df7+T4umb4B3rwxMZRAWZ9eVGPL/mSeWBtHSamBV8b35s4B\n7eUESVQpIT2fR1ZEE3c2R+ZjFiZJzysmLDKGnfHpjO/TjkXjeskMQaJKqeeLmBURze6ETP4zpAPz\nRwfJWgHG6Irg/YGQferftmFhZnt5u/u/dNvhVOat3Ud2QQn/u6E7M67qREOZi05UIb+4lIUbDrJy\nzxmC/Zvx1p2hcsOIqNY30WeZvz4O14YN+OTuflwviwKIauw6kcEjK6LJKdTJSXVtFedBYSZ429/C\nD5bwd0ImDy+PIq+olLcnhTI2tJ2tQ7JPz112Y/DkSOh+k1k3YTcFb35xKYu+P8SK3afp0boJX907\nkKC2ssyrqFrsmWxmR0ZzKrOAh0d0Zs513WSyblGl/OJSnv3uAGv2JjIgsDlvT+pDW29ZHlhUzmBQ\nfLT9OK//cIQOvl6Ey/dTzSkF6+6HuNVlvz+TDi7OOyuBUoovfk/g5U2HaO/jybL7BtG9tQx7qWDd\nDNgX+e/v3W6CySvAAieSdlHw/p2QyeOrYjmTVcCMqzvx2HXd5G56USW9QfHRb8d586ej+DVpxApZ\n/UqY4EBS2fLAJ9PzefSarjw6qov0IIkqZeWX8NiqGLYdSWNMcBteHt9bpo+qqd2fwqa5//4+/HGn\nLnbzi0t5Yu0+Nu5L5vqgVrw+MYSmkjPlZRyHd/uWb3skCnw7W2yTNi14i0v1vPHTUT7ZfgL/5h6s\nmjGEAYGyNLCoWmJWAY+timX3yUzGBLfhxdt608xTDiaickopvv7zFC9uOkRzT1eWTx/E0M4yc4dZ\nleRDQ3do4DwXK6JOZzFreRTpeSWyYE1tbH4Sdn347+9tQuG+H6Gh865wGZ+ax0PL9nI8LY8nbuzB\ng1fLlGMVXD58of1guO8Hi2/WZgXvwaTzPLYqh
 sPncpk8sGxpYJnvUlTnu9gk5q+PQylYckcI4/u2\nk4OJqFJ2QQnz1uzjx4MpjOzektfvCMFXlpQ2n9RD8MHgsn/f9BoMesC28ZiBUorPd57klc2HaePt\nztqHhtLbXxYfMdnhTRA5uXzbY4egqXPPn785Lpm5q2Nxd3Vh6X2DGNZFTqrL+fJmOPV7+bbncqy2\neatXmHqD4uPtZV3RzTzc+OK//RnVo5W1wxAOJrdIx7PfHWBd1Fn6BHjz9p19CPD1tHVYws79nZDJ\n7BXRpOUV8/ToK7jvyo5ygmQuOYnwZs/ybVeMsU0sZpRTqON/q2P58WAK1we14rU7QmjmIT1IJinI\nhMUdy7f1uh0mfGGbeKykVG9g8Q9H+GT7CULbe/PhXX1p00zuC/jHmb/h82vLt83aCy26WDWMagte\nTdPaA18DrQAFfKKUers2G0tIz+fx1bHsPZXFzb1bs+i23vjIHKmiGntPZRG2MpqzWYUy7lKYRG9Q\nfLAtnjd/Pkp7H0/WPjSUYH9vW4flHJKi4ZMR5dsmRUCP0TYJx5ziEnN4OGIvydlFcoJUU5d3U4NV\nr97ZSlpuMbMioth1MpO7B3fg6TFXyD1IFykFz1923O05Hu740ibhmHKFtxR4XCkVpWlaE2Cvpmk/\nKaUOmroRpRTLd53mxe8P0dBF4807Q7gtVLqiRdVK9Qbe3RrPu1uP0dbbg9UPDqFfBxnjbRVKwbaX\nYPvist+fzbbIXbOWkHK+iLDIGP48kcHY0LYsuq2X3GRkDueT4I0ryreNXgIDptsmHjNSSrHsr1O8\nsPEQLRq7serBIfQNaG7rsByDsUJ3QaZTjeWuzN5TZVOO5RTqWHJHCLfL6oz/ssMToGoLXqVUMpB8\n4d+5mqYdAtoBJhW8ecWlzIqI4tcjaVzZpQWv3REsl/qdkDl7AgBOZxQQtjKaqNPZjOvTjoVje0rR\nYg1Kwc/Pwu+XfHRBYx2m
 2N12OJXHV8dSWKJn8YRg7ujnLyfWdVVSAC+1qdjuJFfvcot0PLkuju/3\nJTOye0vemBgqqzOaYvkdcOzH8m0WvsveXiil+OqPBBZ9f4h2zT0Iv3cgV7SRaeoA+H4u/P1p+bZH\no8Gnk23iuUSNxvBqmhYI9AF2GfnbA8ADAAEB/04o7enqgqtLA56/tSd3D+5Agwby5eOk6twTAGUH\nkvXRZ1nw7QE0DZmo21oMBlh42RUt364w/SfwsP8rXSWlBl774TCf7jhJj9ZNeG9KX7r4yeIjdWIs\nJwAWZEED5xhSdDDpPDMjojidWcATN/ZgxlWd5DuqOjER8M1D5dtufBUGP2ibeKysoKSUp9bF8W1M\nEtf08OONO0NljDeAXgcvGLlJz45OjE0ueDVNawysBcKUUucv/7tS6hPgE4D+/furi+0NGmh8cnc/\nucpiL/JS4fPrICvBrGtU17UnAMpuFnn6m/1siE1iYKAPb9wZgn9zuTHNovSl8IKR+YufPAPujnHF\n4lRG2fLA+xJzuHtwB+aPvkKWB64rY92RT52FRs5xEqGUYuXfZ3j2uwM083AlYvogBsk83lUrzIJX\nAyu221FBY2kn0vJ4aFkUR1NzmXt9Nx4e0UVOkMAuhy8YY1LBq2maK2XF7nKl1LqabkSKXTtwbj98\nNKx8W/ebLbKp2vQEAKyLSmRTXDJzr+/GQyO64CIHEsspLYZFfhXbZ8dC80CLbtqcw1++jTnL/PX7\naaDBR3f148ZesjxwnRj74grbD97trR+LhRSUlPL0+v2siz7LlV1a8NakUFrINHVVc5CCxpJ+OHCO\nuatiaeii8dW9A7mqW0tbh2R74WMgYUf5tkdjwKej8cfbmCmzNGjA58AhpdQblg9JmNVbvSH7dPm2\nG16CITMtsrna9gQA3DMkkCGdfenR2jGuLDqkysZjWneOzDoPfykoKeW57w6wak8i/To0553JfWgn\nywP
 XnrGC5r6fof0A68diQcdScnl4eRTxaXmEXduVR0Z1lRPrqhjLi7nx0Lj+FHulegOv/3iUj347\nToh/Mz64q58ca4py4JXyF6xwaQTPpNomHhOZcoV3GHA3EKdpWsyFtv9TSm2yXFiizowdqCavhO43\nWmyTde0JcGmgSbFrKcbmxwSbfHnVdfhLSamBce//wdHUXGaN7ELYtV1lmrraMnacuPY5uHKOtSMx\nypy9AeuiEpm/fj9ejVxYJosCVO3tUMg6Wb5txFMw4knbxGMj6XnFPLoimj+OZzBlUADP3hIkU445\n8NV+U2Zp2AnIKbAj0BXCi0a6dIeFwXXPW3TT0hNgp7LPwFu9KrY/kWAXN6PVZviLW8MGTBrYnu6t\nmjBUipbaMfalBfb4xVXn3oAinZ7nvjtA5N9nGNTRh3cm96FVU3fLRezIjm+FpeMqtttfXlhc1Oks\nZi6PIjO/hMUTgpnY33mG9dTKKwFlV3YvNe8keDrOVKGylq8zSD8G7/Wv2H73eug8ylpRSE+APUmK\ngU+urtj+VCI0amL9eIyoy/CXe4fZ5xgxuxc5FQ5vrNhupwVNXXsDTqTl8fDyKA6fy2XmyM7Mubab\n9AYYY9DDQiOFi53mxeXM2ROglGLZrtMs3HCA1s3KlpXu1a4eLyudcRze7Vu+zX8ATP/ZNvHUgRS8\njuy312Dboortjx+BJta9eUd6AuxEwu8QbuRmRDu7w76uw19EDf39GXz/eMV2BylooPLegKpuhE05\nX0x6Xgnh9w5gRHcjN2kK41f7HWihmQvMMi1mYYme+evjWBd9lpHdW/LWnX1o5lmPpxxz4OELxkjB\n64gq646sJ6vbCCOO/gAREyu229EV3Ytk+IsVnY2CT0dWbHewL62qegOq6gkY0tmXHfNG4uEmx8UK\njH2PPPAbtA21fix1ZI5pMU9l5DNj6V6OpOTy2HXdmDWyHk85Ziw35qeAq2MPBZKC
 15E4zrg7YS37\nVsG6+yu2P50KDe12qiUZ/mJpld2k6IDHirr2Bkixe5lvZ0L0svJtna+Bu52jo6Wq+wIqYzAopn+1\nh7S8YsLvHcjV9XXKsaRo+GRE+ba+98Ct79okHHOTgtfeVbbaETjkl5cwk92fwqa5FdufyQAX+/7f\nWoa/WFBlx4un06Ch4y2XK70BZmRsLCY41fdIdfcFVDb8pUEDjSUTQ2ju6UZ7n3q62JGTDV8wxr6/\nGeuztCPw/sCK7U3awuOHrB+PsA+/vgq/vlSx3fHG3AlzM/aFNecANPO3fizmI70B5lAPihlTegKq\nGv4S7O9t8RjtknOM4TaJUxe8Op2OxMREioqKbB2K6Ypy/p3644ZV/7Z7+Px709Eh8xe87u7u+Pv7\n4+pajwfo27M102D/2ortTvalJWrB2BfWpAjoMdr6sZiZ9AbUkZOOxbyc9ATUwuFNEDm5fNt1C2HY\nbNvEYwVOXfAmJibSpEkTAgMD7X9546Tosv82awRccjexX0+Ld0UqpcjIyCAxMZGOHWW6J7siha6o\njLFi5uonYOT/WT8WYV+M5caEL6DX7daPxTqkJ6Am6sEVf2OcuuAtKiqy/2L3YqF7uTahVutS0DQN\nX19f0tLSrLI9YYKvboGT2yu214ODkqiGsS+rNqEw4zfrxyLsy9+fw/ePlW/TGsCzWbaJx0qkJ8BE\n9bTQvcipC17Afovdygrdtn2sG8cFdvs+1TcfDIFUIzPp1KODkqjE8z6g9BXbJTdEcS68bGSstuSG\nANgbDhsuG6pwx1fQ8zabhGMrTl/w2hWDHs7tM/43GxW6wk68GgiFRq7CyBeWWDsd4lZXbJfcEFDv\nr9qJKigFzxu5Ga+e5ocUvNZQdB4yj1dsb9QEfLtUaN6xYwcPPvggrq6u/Pnnn2RnZ3P//fezcaOR\nJUEv2LhxI7t372bhwoXmjFxYmsytLCoTvaxsztTLSW4IMH7
 seOwwNG1j/ViE/ZEToQqk4LWkjONQ\nXGEqwLIit4rVr5YvX85TTz3FXXfdBcCCBQu4/34jiwtcYvTo0TzzzDM8+eSTeHrW03kEHYkUuqIy\nKQfhwyEV2yU3BMCXo+HUzvJtI+fD1fNsE4+wLz89C7+/Vb7t/q3Qrp9t4rEj9abgfX7DAQ4mGSk+\n6yCobVOevaVnxT9cGJ+74LUP8fFuStj9UwGY/94q/Fq1ZvbsyocvfPbZZ6xatYoffviBzZs3s3z5\nctauXcuiRYsAePPNN4mLi+OLL74gLi6OyZMns3v3bjw9PRkxYgQbN25k4kQjS8wK+yCFrqhM0Xl4\npX3FdskNAXBmN3x+XcV2yQ8BoC+FF3wrtkt+/KPeFLxWcdmNaNMmjWX89LmEPfs6BoOByJUT2Lp1\nK6Ghxtcqj4iIYPr06ezcuZMxY8YwYcIETp48SfPmzWnUqGyZ2NmzZzNixAjWr1/Piy++yMcff/zP\nFd3+/fuzY8cOKXjtkRS6ojKVjbOz7+WhhbVUtnqeHDvERTJ8wSTVFryapn0BjAFSlVK9LB+SZRi9\nEmsOSkFyjNE/BQ4ajW/rt4iOjiYlJYU+ffrQoUMHYmKMP96Y5ORkWrb8d13vBg0aEB4eTnBwMDNm\nzGDYsGH//M3Pz4+kpKTa74swPyl0RVWM5UfYfvA2cqVX1D/1aBUsUQuRU+HwZff2PHYImra1TTx2\nzpQrvOHAe8DXlg3FwZSWQOoB43+7ZMaF6dOnEx4ezrlz55g2bRq5ubkMHz7c6NMiIiIICgoq1+bh\n4VFhpbhjx47RuHHjCsVtUVERHh4etdgZYXZS6IqqGMuPu9dD51HWj0XYH2P58cCvMpuPKFOcBy+3\nK9/WYRjcK+tsVKXaglcptV3TtEDLh+Ig8tMh50zF9qbtoLFfheZx48axYMECdDodERERuLi41OgK\nb7du3UhISPjn95ycHB599FG2b9/OrF
 mzWLNmDRMmTADg6NGj9OrlsBfhnYMUuqIqxvJjxP/BiCes\nH4uwP3++Dz9ctlJe/2kw5k3bxCPsjwxfqDWzjeHVNO0B4AGAgIAAc72s/Ug9BKVFFdv9gqocZ+fm\n5sbIkSPx9vbGxcWlxpv18vKic+fOxMfH06VLF+bMmcPMmTPp1q0bn3/+OSNHjuSqq67Cz8+Pbdu2\n8fLLL9d4G+biLMNfakUKXVEVY/nReyLc/qn1YxH2JzcFlnSr2C7HD3HRstsh/ufybU+eAfemtonH\nAZmt4FVKfQJ8AtC/f39lrte1uTou/WswGPjrr79YvdrIxPGVCA8PL/f7rFmzCA8PZ9GiRXzxxRf/\ntLdv3574+HgAUlJSKCwspHfv3iZvxwLCqW/DX4wVMq6eMD/Z+rEI+7N0HBzfWrFdChlxkVyxE1Ux\ndjLU9z9w6zu2iceBySwNlTHD0r8HDx5kzJgxjBs3jq5du9Y6lHHjxpGRkVHlY06fPs2SJUtqvQ1z\nqFfDX4x9SXkHQFic9WMR9mfHG/DL8xXbpZARFxk7hsxPAVd368ci7JOcDJmVFLyXUgZIjjX+t1rc\nLBAUFMSJEyfqGFSZ6dOnV/n3AQMGmGU7lubwQ1+MHYBa9oCZu6wfi4Ny6qEv8b/AsvEV2+VLSlxk\nbKnoqWugq5E5dkX9FDEJjm4u3/ZMOri42iYeJ2HKtGQrgBFAC03TEoFnlVKfWzowq9IVQtrhiu2N\nmoJvZ+vH48QcduiLsUK36w0wdZX1Y3F84Tjb0JfzyfBGj4rtUuiKi07/BV/cUL6tVS946HfbxCPs\nT/ZpeOuyYYljP4A+U20Tj5MxZZaGydYIxCZykyH3XMV2367QqLH14xH2x1ihGzwJxn9s/VichFMN\nfdEVwYutKrZLoSsuKi2GRRVn8JEcEeXI8AWLq59DGtKPQUlexfbWwdCg5jMpCCdk7OAz6CG46RXr\nx1JP2fXwl0pXR
 0uDhm7Wj8dJOfzwFyliRHWMDXGRxUUson4VvGa4EU1UzimGvxj7grrlbej3X6uH\nUt/Z7fAXYzkyNx4at6zYLuoqHEcc/vL5DXDmr/Jt806Cp49t4hH2J/MEvHNZ7SFjuS2qfhS8Dlbo\nBgYGsmfPHlq0aGGXr1cZhx3+UtnVuts/h94TrB+PsE+y+pXVOdzwl32rYN395dvGfwrBE20Tj7BP\nlx9L/AfA9J+NP1aYjfMWvCX5ZQPAky5bLMK9Gfh0sk1MFhYeHk5CQgLPPfecrUNxDJUVupMjoftN\n1o9H2KePhsO5feXb5GRIXMrYTYshk2HcR7aJR9in8DGQsKN8mwxxsRrnK3hTD8EHg8v+fcMld9Dv\n/aps7K45te5d5ZjOBQsW4OPjQ1hYGADz58/Hz8+P2bNnm/TyhYWFjB8/nvHjxxMaGsp9993H7t27\n0ev1DBw4kJUrV5q8lPDixYvZvHkzHh4eRERE0KVLF5Oe55QMBljYvGL7tB8hYJD146lnHGboy4Yw\n2Ptl+bbRb8CA+2wTjzDKpmO9KztpliLGqux+rHdyLHx8Vfm2mX9DSyOr6wmLcZ6CN+pr+O6Riu2t\nepXNXRe70uohTZs2jfHjxxMWFobBYCAyMpKtW7cSGhpq9PEREREEBQUBkJeXx6RJk7jnnnu45557\nALj11lt5+umnKSws5K677jK52AVo1qwZcXFxfP3114SFhbFx48a676Cj0ZfCC74V2x/eBX5GppQS\nFmH3Q192fwqb5pZvGzAdRtt2YRdhnM3Gehsb4iI3G9lKOPY41tvYCVHPcXBHuE3Cqe8cv+BdMRmO\nbKrYviALjhz5d6JmG9xdHxgYiK+vL9HR0aSkpNCnTx86dOhATExMtc8dO3Ys8+bNY+rUf+ffW7Bg\nAQMGDMDd3Z133ilbVjAjI4NrrrkGgMzMTEpKSvjmm28AWLp06T9LDU+ePPmf/86ZM8es+2n3Sk
 tg\nkZEbih6NdtrhLaIWjm+DpbeVb2vbp2ycrhAXffcoRH1Vvm3OAWjmb5t4hH2O9X4rGLJPlW+TK/82\n5bgFr7Gza7C7hJo+fTrh4eGcO3eOadOmkZuby/Dhw40+9tIrvMOGDWPLli1MmTIF7cIVg4yMDPLy\n8tDpdBQVFeHl5YWvr+8/BXRVY3i1S646aPXlCoSuEF5sXbFdvpzEpdKPwXv9K7bb2bGkPrKr4S8J\nOyF8dPk2WRTAoVhl+MuJX+HrseXbHjsETdtaZnvCZI5V8FY29rLbTTAl0vrxmGDcuHEsWLAAnU5H\nREQELi4uJl3hXbhwIQsXLmTmzJl88MEHAMyYMYMXXniBkydP8sQTT/Dee++ZHMfKlSt58sknWbly\nJUOGDKn1/jiE4lx42UhBO/cYNDYyAbyonwoyYXHHiu1S6NoNuxj+UpwHL7cr39YmFGb8Zpt4RK1Z\ndPiLsfpkyCy44UWzbkbUnmMUvPnp8JqRJX5vfRf63mP9eGrAzc2NkSNH4u3tjYtLzRa1ePvtt5k2\nbRrz5s2jV69euLq6MmXKFPR6PUOHDmXr1q2MGjXKpNfKysoiODiYRo0asWLFitrsiv0z9sUEMv+l\nKJno92UAACAASURBVK+ysdwy/lJcThaOEKZYeTcc+q58m+SJ3bHvgvfSGRcu9dCf0CrI+vHUgsFg\n4K+//mL16tXVP/iChISEf/795Zf/3iV+8eY1FxcXdu3aVeF5//3vf6t8vVdffdXkGBxKUQ68YqR7\n6qlEaNTE+vEI+ySrowlTfTsTopeVb5M8EZc7sxs+v2yhiCcSwMNIT7SwOfsseA9+C6uMXLn9vyRw\n87J+PLV08OBBxowZw7hx4+jatautw3E+JQXwUpuK7f+XDG6e1o9H2K+vx5aNrbuUnBCJy6UdgfcH\nlm+bvQ+ad7BNPMIkVh/rbdDDwst6DSetgB43W2yTou7sq+A99jMsv718W
 +NWMPeobeKpo6CgIE6c\nOGHrMJxPST58dQuc3Vu+/Zn0f2flEAIgbg2svWzeXLmBRFyu6HzZjYt5Kf+2TfgSeo23XUzCZFYd\n6x21FL6b9e/vbUJgxnarbV7Unv0UvO8NgPRLCtvBD8ONL9f5ZZVS9WdWgjpQynrTV9bJ5euPtx8M\n926CBjUbHy3qga9ugZMXvoi0BmVX6rzb2zYmYX/yUuH1S3rg7ggvmytViMutfxBiL9wD0+FK+M93\n8t3jQOyn4O12Y1nBO2MHtAk2y0u6u7uTkZGBr6+vFL1VUEqRkZGBu7u7rUOpnlLg6gX9/gM3vCQ3\nGYnKdb4GTu6AR/aCr5GbXoUAUIaynsTgiXD9IltHI+xZ+4FlQy5n7gJvK6/qJ+rMpIJX07QbgbcB\nF+AzpZT5V3G4/oWyHzPy9/cnMTGRtLQ0s76uM3J3d8ff3wHmpvXtDPOTbB2FcARXhpX9CFGVJq0d\ndticsLL+08p+hEOqtuDVNM0FeB+4DkgE/tY07Tul1EFLB1dXrq6udOxoZJ5NIYQQQghRbzQw4TED\ngXil1AmlVAkQCYyt5jlCCCGEEELYBVMK3nbAmUt+T7zQVo6maQ9omrZH07Q9MoRACCGEEELYC1MK\nXpMopT5RSvVXSvVv2bKluV5WCCGEEEKIOtGqm45K07QhwHNKqRsu/P4UgFKq0jnDNE1LA05d1twC\nSK9TtPbF2fYHjO9TB6WURc5g6kmegPPtU2X7I7lSN862PyDHFEtxtn2SY4plONv+QB2OKaYUvA2B\no8A1wFngb2CKUupATSLUNG2PUqp/TZ5jz5xtf8A+9skeYjA3Z9sne9kfe4nDXJxtf8A+9skeYjA3\nZ9sne9kfe4nDXJxtf6Bu+1TtLA1KqVJN02YBP1A2LdkXNS12hRBCCCGEsBWT5uFVSm0CNlk4FiGE\nEEIIIczObDetmeATK27LGpxtf8A+9skeYjA3Z9sn
 e9kfe4nDXJxtf8A+9skeYjA3Z9sne9kfe4nD\nXJxtf6AO+1TtGF4hhBBCCCEcmTWv8AohhBBCCGF1UvAKIYQQQginZtaCV9O0GzVNO6JpWrymaU8a\n+bumado7F/6+T9O0vubcviWYsE8jNE3L0TQt5sLPAlvEaSpN077QNC1V07T9lfzdKp+Rs+WK5Inl\nPh/JFckVE+NwqjwByRXJFdNInpj4+SilzPJD2ZRlx4FOgBsQCwRd9pibgc2ABgwGdplr+5b4MXGf\nRgAbbR1rDfbpKqAvsL+Sv1v8M3K2XJE8sdznI7li/z/2kCvOlieSK5IrkifmzxNzXuEdCMQrpU4o\npUqASGDsZY8ZC3ytyvwFeGua1saMMZibKfvkUJRS24HMKh5ijc/I2XJF8sRyn4/kip2zk1xxtjwB\nyRXJFdNInpj4+Ziz4G0HnLnk98QLbTV9jD0xNd6hFy6rb9Y0rad1QrMYa3xGzpYrkieW+3wkVyRX\nzLUNR8oTkFwByRVTSJ6Y+PmYtPCEqFIUEKCUytM07WbgG6CrjWMS9kfyRJhKckWYSnJFmELyBPNe\n4T0LtL/kd/8LbTV9jD2pNl6l1HmlVN6Ff28CXDVNa2G9EM3OGp+Rs+WK5InlPh/JFckVc23DkfIE\nJFdAcsUUkicmfj7mLHj/BrpqmtZR0zQ3YBLw3WWP+Q6458IddoOBHKVUshljMLdq90nTtNaapmkX\n/j2Qsvc0w+qRmo81PiNnyxXJE8t9PpIrkiumcLY8AckVyRXTSJ6Y+PmYbUiDUqpU07RZwA+U3TX4\nhVLqgKZpD174+0fAJsrurosHCoB7zbV9SzBxnyYAD2maVgoUApPUhdsI7ZGmaSsou2OzhaZpicCz\ngCtY7zNytlyRPLHc5yO5IrliCmfLE5BcQXLFJJInpn8+srSwEEIIIYRwarLSmhBCCCGEcGpS8Aoh\nhBBCCKcmBa8QQgghhHBqUvA
 KIYQQQginJgWvEEIIIYRwalLwCiGEEEIIpyYFrxBCCCGEcGpS8Aoh\nhBBCCKdmtpXWLtWiRQsVGBhoiZcWVrZ37950pf6fvfMOi+Lq4vA7KgqWiGKvWKPYUMGaZnrxS6Ip\n1tgFjcb0nphi2pfkiyXVjt0YY5pJTDPNEgXEig07YgOk9937/YEGWUEW2N2Z2T3v8/DIXGbvnJn9\neefce889V9V1Rt2iE/dCtCLYg+hEsBfRimAP9urEKQ6vv78/ERERzqhacDGaph1zVt2iE/dCtCLY\ng+hEsBfRimAP9upEQhoEQRAEQRAEt8auEV5N044CqYAFyFNKBTnTKMG8iFYEexCdCPYiWhHsQXQi\nlERpQhr6KaXinWaJ4E6IVgR7EJ0I9iJaEexBdCIUi1NieIsiNzeX2NhYsrKyXHVJ0+Lt7U2TJk3w\n8vJyyfUsVsWMXw9wW4cGdGxc0yXXLA7RSelwtVYOn0tj6T/Heemu9lSooLnkmsUhWrEfV+tEKcXs\nvw7TpYkvvVv5ueSaxSE6KR2u1sqp5Ew+/eMQL90VQOVK+kZZilbsx9U6AVj6zzHqX+XNLQH1y/R5\nex1eBfyqaZoFmK2UmmN7gqZpIUAIQLNmzS6rIDY2lho1auDv74+m6fuiNDJKKRISEoiNjaVFixZO\nv15yRi6Pfh7FH/vPoYEjHN4rakV04jhcrZU/D5zjkeXbqFSxAqP6+NPMr2p5qpM2xUW4Wic5eVZe\n+GoXqyNjGdazmSMcXmlTXISrtbInLpkxYeGkZ1sYHNyMgEZXlac6aVNchKt1opTi/Z/38/Hvh7ir\nU8MyO7z2dqeuUUoFAncAkzRNu64Ig+YopYKUUkF1616eHSIrKws/Pz8RUQlomoafn59LepgHzqRy\nz8cb2BgTz5sDOvLErVc7otorakV04jhcpRWlFPM3HGH0wq008vXhm0l9y+vsgrQpLsOVbUpieg7D\n529hdW
 QsU25qwxv3dnREtdKmuAhXauX3/Wd58LPNVNQ0Vk/sXV5nF6RNcRmu1EmuxcpTX+zk498P\nMTi4KTMHB5a5LrtGeJVSJy/8e1bTtK+AHsBfpb2YiMg+XPGc1u0+xROrdlCtSiVWjO9FkH9th9Tr\nCK2ITuzH2c8qO8/Cy1/vZlVELLcG1Gf6oECqVSl/JJS0Ka7FFc8p5mwaYxeFcyo5i5mDA7knsLFD\n6pU2xbW44lkt23KMqd/soV2DGiwYFUz9q7zLXae0Ka7FFc8pLTuPiUsj+ftgPI/f3JYpN7Uu13VL\nHOHVNK2apmk1Lv4O3ArsLvMVBV2xWBXv/7SfCUu30bZ+DdY+co3DnF3RinsRn5bN8HlbWBURy5Qb\nW/PZ8O4OcXZFJ+7Hpph4Bn6ykbSsPFaM7+kwZ1e04l5YrYq3f9zLi1/t5ro2dVgV2tshzq7oxP04\nm5rFoNmb2XQogf/e14lHb25TbifbnpCG+sAGTdN2AFuB75VS68p1VRPx999/06FDBwIDA8nMzOTU\nqVP079//ip9Zu3YtU6dOdZGF9pOcmcu4ReF89HsMg4KasjKkl0Mam0vwWK24k04gP7bu7g83sOtk\nMh8O6coTt17tyEVqHqsTcD+trNh6nBELttKgpjdfT+pL9+aO6UBfwGO14m46ycq18MiKKGb/eZjh\nvZoxd0SQQzrQF/BYnYD7aeXQuTQGfrKJI/HpzBsZxKDgy+Oty4RSyuE/3bt3V7ZER0dfVmYGQkND\n1ZIlS/49fuqpp9TXX399xc9YrVYVGBio0tPTy3xdRz+vA6dT1A3v/a5aPf+9Wrz5qLJarXZ9DohQ\nTtCIEp04RCdKOf6Z/bAzTrV76UfV661f1c4TSXZ/TrRiH+7SpuRZrGrad3tU82fXqhHzt6jkzBy7\nPic6sQ93alMS0rLVwE82qubPrlWz/4yR94+DcZc2RSmlIo4mqi6v/aS6T/tZ7Thx3q7
 P2KsTj9lp\nberUqcyYMePf4xdffJGZM2de8TPz5s1j1apVvPzyywwbNgyAL7/8kttvvx2A6dOnM2bMGAB27dpF\nx44dycjIQNM0brjhBtauXeukuykdP+05zb0fbyQ1K48VIb14qFdziVMqBk/WifVCerqJy7bRrmEN\nvpncl05N9E1TZ2Q8WSvp2XmELolg3oYjjOzdnPkjg7jK23XpicyEJ+sE4Eh8OgM/2cjuk8l8Mqwb\nIde1kvdPMXi6Vn7ac5qhc//B18eLLyf2oXMTX4fW77I8vJfy2nd7iI5LcWidAY2u4pX/dCj272PG\njGHgwIE89thjWK1WVq5cyfr16wkMLHrF3/Llyxk3bhwbNmygf//+3H///Rw5coRatWpRpUoVAB59\n9FFuuOEGvvrqK958801mz55N1ar5q9eDgoL4+++/efDBBx16n6XhogMza30MXZrU5LOHutOwpo9u\n9pQW0YnryMjJ46kvdvDDrtMM7NaYtwZ0wturoq42lQbRiuuIS8pk7KII9p9O4bW7OzCyj7+u9pQG\n0YlrCT+aSMjiCDRNY/n4XnRvXktvk+xGtOJalvxzjFe+2U3nJr7MHxmEX/UqDr+GLg6vHvj7++Pn\n50dUVBRnzpyha9euNG/enO3bt9tdx6lTp7g0lUmFChUICwujc+fOhIaG0rdv33//Vq9ePeLi4hx6\nD6UhJSuXx1du57d9Z3mgexOm3dvRVA6MXniaTgBOJmUyflEEe0+n8MKd7Rh/bUsZgbEDT9TKjhNJ\njFscQVaOhQWjgrnh6nq62mMGPFEnAGt3xvHEqh009vUhbHQwzf2q6W2S4fFErSileO+n/XzyxyFu\nalePj4Z2w6eyc3wVXRzeK/VwnMm4ceMICwvj9OnTjBkzhtTUVK699toiz12+fDkBAQGFynx8fC7L\nO3fw4EGqV69+mWiysrLw8dFnNDXmbBohiyM4npjBa3d3YERvc4
 YwiE6cT+SxREKXRJKda2XBqGD6\nmdSBEa04nx92neKJVdupU70Ky8b1pG39GrrZUlZEJ85HKcVnfx7mv+v2EexfizkPBVGrWmXd7Ckr\nohXnk5Nn5bk1O1mz7SRDejRj2j0dqFTReZG2HjPCCzBgwACmTp1Kbm4uy5cvp2LFiqXqObVt25aj\nR4/+e5ycnMyUKVP466+/mDx5MqtXr+b+++8H4MCBA3Ts6JCk66Xi5z2neWLVDry9KrBsXE96ttR3\nW08z4gk6Afgi4gQvfrWbRr7erAwJonU98zkweuMJWlFK8ckfh3jvp/10a+bLnBFB1HHCdKM74wk6\nAcizWHn5mz2s2Hqc/3RpxHv3d5aZxVLiKVpJzcrl4WXb+PtgPE/c0pZHbixfjl178CiHt3LlyvTr\n1w9fX18qViz9f8Jq1arRqlUrYmJiaN26NY8//jiTJk2ibdu2zJ8/n379+nHddddRr149fv/9d95+\n+20n3EXRWK2Kmb8dZOZvB+ncpCafDe9OI1/zxOsaCXfWCeS/lN75cR/zNhyhb2s/Ph7aDd+q5huB\nMQLurpXsPAsvrNnNl9tiuSewEf+9TxyYsuDuOoH8TQImLdvGnwfO8fANrXjKsakMPQZP0MrZlCxG\nLQxn/5lU3r2/Mw8GNXXNhe1J5VDaH6Om+7BYLKpLly7qwIEDZa5jzZo16sUXX7ziOadPn1Y33nhj\nma+hVOmeV3JmjhobFq6aP7tWPfH5dpWZk1eua18KHpgWxkw6Uap0zywpI0eNmL9FNX92rXrlm90q\nN89S7utfRLRSNozYpiiVn0rqgU83qebPrlUzfjlgdyqpkhCdlA2jtilKKRWXlKFum/6navn892rF\nlmPlvv5FRCtlw6htilJKHTyTqvq8/Ztq//KP6vd9Z8p1/YvYqxOPSUsWHR1N69atuemmm2jTpk2Z\n6xkwYAD+/v5XPOf48eP873//K/M1SsOhc
 2nc+/FGft9/llf/E8D7D8gITHlwV50AHD6XxoBPNrIx\nJp63B3bi1budGy/l7rizVmLO5rcr22OTmDWkq0N2OfJU3FknANFxKQz4eBOx5zNZMCqYwT0ctEmA\nB+LuWok8lsj9n20iO8/C5yG9Xb7o1WNCGgICAjh8+LBD6ho3btwV/x4cHOyQ65TEr9FnePzz7VSu\nlB+v20vidcuNO+oE4O+D55i0bBuVKkpst6NwV61sOBjPxGWRVKlUgZUhvejWzDyppIyIu+oE4I/9\nZ5m0bBs1vL1YFdqbgEZXufT67oY7a+WnPaeZsiKKRr4+LBrdg2Z+VV16ffAgh9edsFoVH66PYfqv\nB+jUOD+/bmOJ1xWKQCnFwo1HeeP7aNrWr8HcEUE0re36hkYwB8u2HGPqN3toXbc680cF0aSWaEUo\nmuVbjvPyN7tpW78GC0cF06CmQ7epF9yIJZuPMvXbPQQ29WX+yGBq65S1Qxxek5GalcuTq3bwc/QZ\nBnZtzFsDzbVBgOA6svMsTP16D59HnODWgPpMHxToyL3rBTfCYlW89cNe5m84Qr+r6zJrSFdqyM5p\nQhFYrYr3ft7Pp38c4oar6/LR0G5Ul3ZFKAKlFO/+lK+Vm9vX58MhXZ2WY9ceRKUm4vC5NMYvjuBo\nQgZT+wcwuq+/xNUJRRKfls2EJZFEHDvPIze25vGb28qKaaFI0rLzmLIiivX7zjKqjz8v3dVeYruF\nIsnKtfDkFzv4fucphvZsxuuyDkAohpw8K899uZM1Ua7JsWsP4vCahPX7zvDoiu14VarAkrE96NOq\njt4mCQYlOi6F8YsjSEjP5sMhXflPl0Z6myQYlJNJmYwNC+fg2TSm3duRh3o119skwaCcT89h/OII\nIo6d57k72hF6nezIKBTNpTl2n7q1LZP6OT/Hrj1I16wE/P39iY+P160+q1Ux67eDjF0UQTO/qnw7\nua84uwZEb51cZN3u
 U9z36SYsVsUXoX3E2TUgRtHK9hNJ3PPRRk6ez2ThqGBxdg2GUXQCcDQ+nYGf\nbmLnyWQ+HtqNCde3MoQDI+RjJK2cScli0Ox/2Hwogffu78zkG42T4UUcXicRFhbGq6++Wq460rLz\nmLgskg9+OcA9XRqxekIfWUTiZjhCJ5AfKzXz14NMWLqNqxvU4NvJfenUpGb5DRQMg6O0AvD9zlMM\nmr0Zn8oVWPNwH65rW9ch9Qr640idQH4qqQGfbCQpI4fl43pyV+eGDqtb0BdHayXmbBoDP9nE0YR0\n5o8K5gFXbShhJx7j8E6dOpUZM2b8e/ziiy8yc+ZMuz+fmZnJHXfcwdy5cwkPD6dz585kZWWRnp5O\nhw4d2L17t911vfvuu3Tq1IkePXoQExNT5Dl5FisDPt7Ir3vP8tJd7Zk+KFDXYG9PwWw6AbAqxeTl\nUUz/9QADuzVmZUgv6l0lK6adjRm1opTiw98OMmn5Njo2rsnXD/elTX3ZUtqZmFEnF1m7M44hc7dQ\n08eLNQ/3Jci/tt3XEkqPmbUSfjSR+z7dRHaelc9DenO9ATvR+sTw/vgcnN7l2DobdII73in2z2PG\njGHgwIE89thjWK1WVq5cyfr16wkMDCzy/OXLlxMQEABAWloagwcPZsSIEYwYMQKAu+++m5deeonM\nzEyGDx9eqv2oa9asya5du1i8eDGPPfYYa9euLfT3lMxczqZmE5+WzeIxPejb2kNDGEQnV9QJ5C8M\niE/N5ofdp3jhznaMv9ZD4+pEKyVqRSnFE6t28FXUSe4NbMQ7nrhNsOikRJ1c5LM/D/HOj/sIal6L\nOSOCdEslpRuiFbu1sm73Kaas3E4TXx8Wjelh2NSXHrNozd/fHz8/P6Kiojhz5gxdu3alefPmbN++\nvcTP3nPPPTzzzDMMGzbs37KpU6cSHByMt7c3s2bNAiAhIYGbbroJgMTERHJycvj6668BWLJkCZ06\
 ndQJgyJAh//77+OOP/1unUopzqdmcTsmiUgWNbydfY1jhuCtm0MlF0rPzOJaQQZ5VsWBkMP3auXbX\nGk/HTFrJs1iJT8vhq6iTPHlLWybfaIxFJJ6AmXQC+e+hpIwc3vnxMP07N+T9B7p4XsdIJ8ymFYBF\nm47y6nd76NrUl3k65ti1B30c3iv0cJzJuHHjCAsL4/Tp04wZM4bU1FSuvfbaIs+9tOfUt29f1q1b\nx9ChQ/99SSQkJJCWlkZubi5ZWVlUq1YNPz+/f4UZFhbG0aNHi4yPufRFc/F3i1URez6D5MxcfH0q\nU6lGFXF2RSdF/g6QmJ7DyaRMvCpq1K1Rhc6e7uyKVor8HfJTSR1NSCfHYuWjoV3p39mDFzKKTor8\n/SIWq+J4YgZp2RYmXN+KZ2672nPTGYpWivz9IkopkjNzeeXbw9wSUJ9Zg/XNsWsPdsfwappWUdO0\nKE3Tih/XNjgDBgxg3bp1hIeHc9ttt1GjRg22b99e5M9FEQG8/vrr1KpVi0mTJv1bFhoayrRp0xg2\nbBjPPvtsqez4/PPP//23d+/eZOdaOHQujZTMXBrW9KFpbR8ZfdERo+oE8huZuKRMYs9nUK1yRVrX\nrY6X5MHUDSNrBfLTAx06l4bVCnWrV/FsZ1dHjK4TgNw8K4fPpZGWlUetql48d0c7z3V2dcQMWrEq\nxYnzmaRm5TGsZzM+G97d8M4ulG6E91FgL2DazbIrV65Mv3798PX1pWLF0n05M2fOZMyYMTzzzDN0\n7NgRLy8vhg4disVioU+fPqxfv54bb7zRrrrOnz9P586dqVKlCnPDFhNzLg0A/zrVTL+7kaZpFYEI\n4KRSqr/e9pQFI+pkxYoV5FmtnEjMJDUrF7/qVWhU01s6RjpjVK0AJKRlE5eURRWvCvj7VeNQsnSM\n9MLIOgHIzMmfBbBYFf51qhKb6jHRjobD6FqxWK0cS8ggLTuPmj6VeOPejuZ5
 DymlSvwBmgC/ATcC\na0s6v3v37sqW6Ojoy8pcjcViUV26dFEHDhzQ2xRltVrVmeRMtePEebX/dIrKzs0r9HcjPC+llAIi\nlB0aUQVaeQJYLjpxLFk5eWrfqRS180SSik/LKvQ3IzwzpcqklYpAlGjFsVitVnXyfIbaceK8OnIu\nTeVZrEopYzwvpUQnRiMlM0ftjk1S0XHJKiM7/z1khGemVOm1Upof0UrpycmzqP2n899DCWnZhnhe\nStmvE3u7/DOAZwBrcSdomhaiaVqEpmkR586dK6Xb7Xyio6Np3bo1N910E23atNHVlotxUqdTsvD1\nqUzrutWpXMn40wEloWlaE+AuYJ7etpQVI+nkIqlZucScS8NiVbSoWw2/alX0NslRXJw1MiVG1IrF\nauVoQgbxadnUqV6F5n5VqWj+aWnRiZNITM/maHwGXpUq0KpudVNMS18Js4deGlkrWbkWDp1NIyfP\nin+dqoZenFYcJc5baJrWHzirlIrUNO2G4s5TSs0B5gAEBQUph1noIAICAjh8+LDeZpCdZ+FYQgbZ\nuRYa1vSmTvUq5pkOKJmLHaNiE3tqmhYChAA0a9bMRWbZj1F0AvmzLwlpOZxKzqSKV0X8/aq6RccI\nCnWO3iR/VsB0GEkrADl5Fo4mZJCda6Wxrw9+1c3fMRKdOAelFGdSsjibmk0Nby+a1XaLjhGYPPTS\niFqB/IxARxPS0dBoVbcaPpXNGfJizwhvX+BuTdOOAiuBGzVNW1qWi+WPPHsuqVm5xJxNI9dixb9O\nNerWKDoG04zP6dKO0ZXOU0rNUUoFKaWC6tYtOjG1Ge/f0ViV4uT5TOKSM6nh7UWrYmYBTPysHDJr\nZOL7dygZ2XnEnE2/0LZUvczZNfFzKlEn9mDi+3c4VqviRGImZ1OzqV2t8mWzAGZ9Vo6aYTTr/TuL\n5IwcDsenU6lCBVrXK3B2zficSnR4lVLPK6WaKKX8gcH
 AeqXU8NJeyNvbm4SEBFM+pPKilOJsahZH\n49PxqliB1vWqF7s4TSlFQkIC3t6m2ynLIR0jT9bJRXItVo6cSycxI4d6NYqfljarVhzVORKt5JOU\nkcOh+HQqVIBWdS9vW9xdJyV1jEQnBeRZrByJTycpM4cGNb1p7OtDBa2ws2tGrVyg3J1o0Uph4tOy\nOZaYgY9XRVrVrfbvoItZdeKycekmTZoQGxuLEeN7nYlVKZIycsnIsVC1ckV8q3pxOPHKU0fe3t40\nadLERRY6BqXU88DzABdCX54qS8fIU3VykVyLlYS0HCxKUatqZc6nVuR8XPHnm1ErFHSO7gS8gas0\nTVtaWr14ulYAUrJyScnMo0qlCvhVq8yR80W3Le6sk5LC6UQn+eRZrCSk55BnzW9bElIrklDEeWbU\niqNCL0Ur+SiV37akZuXh41WBStUqczChcNtiRp2UyuFVSv0B/FGWC3l5edGiRYuyfNS0nEjMYPzi\nCPafSeWZ29oxobeHbvtaCjxRJxdZt/sUj3++g5o+XswZ0Z3OTXz1NskpOKpz5Mlaycq18NyXO/l6\nexwDuzXm7YGdqOIm8d0XEZ04jshj5xm/OAKrUswdEUR3/9p6m+RoHNKJFq3kb1f/9OodfLM9juG9\nmvHa3R3dJb7bc7YWdjV/HzzHIyuisFoVYaN7cH3bouNV3ZHydIw8EaUUs36LYfqvBwhs6such7pT\n7ypzTRUJriMhLZuQJZFEHjvP07ddzcM3tJKOtFAsP+w6xWOfb6dhTW/CRvegRZ1qepvkcBzVOfJ0\nUrJyCV0cyebDCW7ZtojD62CUUsz9+zDv/LiPNvVqMPuh7vi7YQMjOIbMHAtPrd7B9ztPMbBrj2RH\nVwAAIABJREFUY94a2Mmj9q2XzlHpOHAmlTFh4ZxLzeaTYd24s1NDvU1yCaKT0nPxXfTWD/vo1syX\nuSOC3CJzh+AcTidnMWrhVmLOpv
 HBg10Y2M1c4Qr2IA6vA8nMsfDslzv5dkccd3ZqwHv3d6FaFXnE\nQtHEJWUyfnEE0adSeP6OdoRcJyEvQvH8sf8sk5dH4VO5IqtCe9OlqXuGvAjlJ89i5ZVv97Bsy3Hu\n6tSQ/z3YxWM60tI5Kj0HzqQyasFWkjNzWTg6mGvbuOeMtHhjDuJEYgYhSyLZdzrFLacCBMcSeew8\noUsiyc61MH9kEDe2q6+3SYKBWbz5KK9+u4erG1zF/JFBNPL10dskwaCkZ+fxyIoo1u87S+j1LXn2\ntnZUcJMYTMHxbD2SyLhF4VTxqsjnob3p2Lim3iY5DXF4HcDGmHgmLd+G1apYMCqYflfX09skwcCs\njozlhTW7aOjrzYrxPWlTv9h9OgQPJ89iZdraaBZtPsbN7esxc3BXmTUSiuVMShZjwsLZdzqVN+7t\nyPBezfU2STAwF+O7m9byIWx0D5rWrqq3SU5FWs5yoJRi/oYjvPXDXlrVrc6cEUFuuSBAcAwWq+Kd\nH/cy9+8j9GnlxyfDuuFb1XzbMwquITUrl8nLo/jzwDnGXdOC5+9s7zarpQXHs+90CmMWhpOUmcu8\nkUEy8CJckYUbj/D62mi6NavFvBFB1DLhVsGlRRzeMpKZY+G5NTv5Znsct3dowPsPdqG6jLwIxZCS\nlcuUFVH8sf8cI3s356X+AXhVtGejQ8ETOZGYwdhF4Rw+l85bAzoxtKfxtuEWjMNfB87x8LJtVKuS\nH9/tztPSQvmwWhXvrNvHnL8Oc1uH+swc3NVj4rvFQysDJxIzmLA0kuhTKTx1a1sm9Wst8bpCsRyJ\nT2fconCOJWTw5oCODOsp04xC8UQeO0/I4ghyLVYWjelB39Z19DZJMDCfhx/nxa9207pedRaODqZh\nTYnvFoomO8/CU1/s5LsdcYzo3ZxX/tPBo2aNxOEtJZsuxOvmWRULRgbTr51MGwnF8/fBc0xato2K\nFTSWjutJr
 5Z+epskGJhvtp/k6dU7aVjTmwWjgmlVt7reJgkGRSnF/34+wEe/x3Bd27p8PLRrsVvW\nC8KlOXafuf1qJl7veQvrxeG1E6UUCzYe5a0f9tKyTjVmP9SdlvIyEopBKUXYpqO88f1eWtetzryR\nQW6/IEAoO0opZvx6kJm/HaRHi9rMHt7dI2LqhLKRnWfhmdX5IXWDg5sy7d6OEiIlFMulOXanD+rC\ngK7ul2PXHsThtYPMHAsvfLWLr6JOcmtAfT4YFCjxukKx5ORZmfrNblaGn+CWgPpMF70IVyArN995\n+XZHHPd1a8LbAztRuZI4L0LRJGXkELIkkq1HEiUFplAiB86kMnLBVlKz8ggb3YNr2nhuiJS8hUvg\nZFImoUsi2BOXwhO3tGVyv9aS01Aolvi0bCYujST86Hkm92vNE7e0Fb0IxXIuNZuQJRFEHU/y2GlG\nwX6OJ2QwKmwrsYmZzBrSlbu7NNLbJMHAbDmcwPjFEXh7VeTz0F50aOTZixnF4b0Cmw8lMGn5NnLz\nrMwbEcRN7WVzAKF49p5KYdyiCOLTspk5OJB7AhvrbZJgYPafzt8mOCE9m8+Gd+P2jp6xTbBQNrYd\nP8/4RRFYlGLpuJ70aFFbb5MEA/P9zlM8/vl2mtb2YdGYHjSpZbKQuqxkWDEErnsaWvVzSJXi8BaB\nUoqFG4/y5g978ferypwRQbJ4RLgi63af5olV27nK24svJvSmcxPZ9lUont/3n+WR5VFUvbBNsOhF\nuBLrdp/i0ZXbaVDTm4WjgmX9iHBF5m84whvfR9O9WS3mjQwyX773Q+thyYD8309cLw6vs8jKzY/X\nXbPtJDe3r8/0QV1k5atQLEopPlwfwwe/HCCwqS9zHupOvau89TZLMChKKRZtOsrra6Np1+Aq5o8K\nkjRSQrFc3NzozR/20rWpL3NHBOFXvYreZgkGxWpVvH1hc6PbOzRgxuBA8+XY/XI87FqV/3
 u3kXDD\nsw6rWhzeS4hLyiR0SSS7Tibz2M1tmHJjG4m/FIolM8fCU6t38P3OUwzs2pi3BnYyX+MiuIw8i5XX\n10azePMxbgmoz4xBgbJNsFAsl+rljo4NmD7IhM5LUSy9D3IzYcQ3UFEGkxzFpTl2R/Xx5+X+AebK\nsZt2Ft5vU3A86nvwv8ahl5DW9gL/HE5g0rJtZOdZmTsiiFsCJF5XKJ64pExCLixmfO6OdoRe11IW\nGwnFknJhm+C/Dpwj9LqWPHN7O3O9jASXkp6dx5QVUfy27ywh17XkudvbmX/wJfkkTA8oOK4g7oej\nSM7MZcKS/By7pnwfLb4XDv9ecPz8Saji+LAdj1fcxSnGad/vpXnt/Hjd1vUkPkoonshj5wldEklW\nrkUWMwolciIxgzFh4RyJT+edgZ0Y3EO2CRaK52xKFmMWhRMdl8K0ezvyUC832Jlxy2z48Zn83ytW\nzndozOSQGZi4pExGLwzncHwaMwYFcm9Xky2WftUmc8SryU67lEc7vFm5Fl76ejerI2O5uX09PhgU\nyFUSrytcgS8jY3l+zS4a+nqzYnxP2tSvobdJgoGJPJZIyOJI8qyKxWN70KeVm+bAjP4GVo2AQUuh\n/X/0tsa07D+dyuiFW0nKzGW+O+zkmZsFb14yIHDLNOg7RT973Iz9p1MZtbAgx66ptiFPiYMP2hcc\n1+8IEzc69ZIlOryapnkDfwFVLpy/Win1ilOtcgGnkjOZsCSSHbHJTLmpDY/dJPG6QvFYrIr/rtvH\nnL8O06eVHx8P7SY7YQlX5OuokzyzeieNfPO3CXbLlfVWC8wKhKTj+ceV3fAeXcTGmHgmLInE50Lm\njo6NTZ4z9ZvJELWk4PjRnVDLDUarDcI/F3Ls+njl6yWg0VV6m2Q/X4yGPWsKjiduhvoBxZ/vIOwZ\n4c0GblRKpWma5gVs0DTtR6XUP062zWlsPZLIw8siycyxMPuh7tzWo
 YHeJgkGJiUrl0dXRPH7/nOM\n6N2cl/sHyDaeQrFYrYoZvx5g1voYeraozWfuuk3w8X9gwW0FxxM2QINO+tljYlZFnOCFNbtoVbc6\nC0YH09jX5Jk7bKepX0mSEAYH8t2OOJ5ctYNmflUJGx1srhy7LgxhsKVEh1cppYC0C4deF36UM41y\nFkoplv5zjNe+i6ZZ7aqsDOlF63oyJe0I3HUm4Eh8OuMWhXMsIYO3BnRiaE8Pir/MPA//9YeGXSDk\nT3lh2UFWroUnv8jP3PFgUBPeuNcNtwlWCl67JG9wk2AY+4voowwopfjglwN8uD6Ga9vU4eNh3cwd\nVnd6F3x2ycr6qnXgmUP62eOGzPv7MG98v5dg/1rMHWGiHLvpCfBey4LjGo3gyb0uNcGuGF5N0yoC\nkUBr4GOl1JYizgkBQgCaNTOeU5CVa2HqN7tZFRHLje3qMWOwxOs6GLebCdhwMJ5Jy7dRQYOl43rS\nq6Wf3ia5jo2z4JeX83+PP+hQZ8ZdO0dnU7MYvziSnbFJPH9HO0LMtlLaHjZ9CD+/VHA8bDW0uUU/\ne0xMdp6F577cxVdRJxkU1JQ3BnQ098zRa7VBWQqOJ4VD3bb62eNmWK2KN3/Yy/wNR8yXpm7lMNi3\ntuB4/Hpo3N3lZtjl8CqlLECgpmm+wFeapnVUSu22OWcOMAcgKCjIUCPAp5OzCF0ayY4TSTxyY2se\nv7mtxOs6GHebCbiYuaN13erMGxlE09ommjIqD+nx8F6rguO+j8Etrzn6Km7XObq4rXRieg6fDuvO\n7R3dMEzKdiryhTioXE0fW0xOckYuIUsi2HIkkadubcukfq3N2zmyWuH1WoXLXDhN7Qlk51l4ctUO\n1u48Zb4cuzqGMNhSqiwNSqkkTdN+B24Hdpd0vhEIP5rIxKXbyMzJ47PhbvoiKi1//Bf+eCs/8XfL\nGxxWrTvMBOTkWZn6zW5Whp/gloD6TB8USHVP
 2RzAtmF6cj/UcPz/F3fqHAGs33eGR5ZHUd27El9M\ncIPFRrYc/gMW31O4zEUvLXecDTiRmMGohVs5kZjJzMGB3BNosjRSlxI+D75/suC41yS4/S397HFD\nkjNzCVmc3zky1cxRcixM71C4TOeOkD1ZGuoCuRecXR/gFuC/TresnCilWLrlOK99u4emtatKCimA\n+Bj46JJphOqOzR9r9pmAhLRsJi7dxtajiTx8QyueuvVqz5gJOPgrLLuv4LhxEIz/zamXdIfOkVKK\nhRuP8sb30bRveBXzRwbToKabbStt2wl6+B+o177oc52DW80GbD+RxLhF4eRaFEvG9qCnmcOkbLXx\n4mnw0mexnTt2jCA/m9TIBVs5Ep9urs6RrTYeCIMOA3Qx5VLsGbpqCCy68IKqAKxSSq0t4TO6kp1n\n4ZVv9rAy/AQ3XF2XmYO7UtPHg+N1rVYIuwuObyooe+YIVK3tlMuZcSbg4pR0fFq2uRqW8mLbMDlh\nO8eiMHvnKNdi5dVv97Bsy3FuDajPjMGBVK3sRjMB54/BzM6Fy3QYnXGn2YB1u0/z6Moo6l/lzcLR\nwbQya5q6hEPwYbfCZfqHMLhVxwjyc+yOXLCV9Ow8Fo3uQR+z5Ng1cIYOe7I07AS6usAWh3AmJYsJ\nSyOJOp7EpH6teOKWq80T6+IMZgbC+SMFx/fNh073O/wyZp0JAPhpz2ke/3w7V3l78cWE3nRu4lvy\nh8zOnq/hi5GFy/RxaEzXOUrOzGXy8m38fTCeCde34pnb3GwmwPaF9eASCLhbH1soeTbADDMBCy7M\nBHRp4su8kUHUqV5Fb7PKhq027vkYug7Xx5ZLcKeOEcDmQwmELImgauWKrJrQm/YNTZBj13b9Bxih\nI1QINxqSyN/VaMLSbaRn5/HpsG7c0amh3ibpR1G98JcToKLTvnLTzQQopfhofQz/++UAXZr6Mveh\n7tS7ys2mpIvC9qU1/nd
 o3K3oc52AmTtHxxLSGROWn6bu3fs682BwU71NchzZqfB2k8JlBnhhlTQb\nYOSZAItVMW1tNGGbjnJ7hwbMGGyilfW2GGjxUVG4Q5gUFM6xu2hMD3PkZLbVRudBMHCOPrZcAbdx\neJdvOc4r3+6mka8PS8f25OoGHhyvayu+4HFw1/+cekmzzQRk5lh4anV+vtQBXRvz9sBO5n0R2cu2\nJfDt5MJl+ry0TNc5gvwFsKFLIrEqxZKxPendysTxl7bYthltboNhq/SxpRjMNhuQkZPHlBXb+XXv\nGcZf24Ln72hvzpmAn16EzR8VLjOYswvmD5OCghy7PfxrM3dEEDWrmiAU07btmHoeKhgzvZ7pHd7s\nPAuvfhvNiq3Hub5tXWYN7moOkTiDiIWw9rHCZQZsmPTmVHIm4xdHsCcuhefuaEeoWVa9lofLFh9t\ngXrtdDHFbJ0jgDXbYnnuy100qeXD/FHBtKjjJum4bDeRAJiaCBWM0fkz62zA2dQsxi2KYPfJZF6/\npwMjevvrbVLZsG03xv4CTXvoY4udmK1jBPk5dt/4fi8LNh7hzk4N+OBBE8wEGHRG6EqY2uE9eyFe\nd9vxJCZeWFXvkfG6ReVBHLkWWlyrjz0GJvLYeSYszd9Wet6IIG5q79hMFYZj3i0Qu7VwmcEbJSNh\ntebvhPXR7zH0bunHp8O7mWdno5J4rRYoa+Ey42nDdLMBB86kMnphOInpOcw1axtjMmfGrB0juLA7\n46odfL/LRDl2/9ceUuMKjltcDyO/1c8eOzGtwxt57DwTl0aSmpXHx0O7cVdnD43Xfb8tpJ0pXGbg\nhklPvoyM5fk1u2hQ05vl4zwgTZ3t6MzEzVA/QB9bTEhmjoWnvsh/EQ0Obsrr93R0n22CbbXx6A6o\n5a+LKVfCbLMBG2PimbA0Em+viqwK7U2nJibMyWyrjYqV4eVz+thiP6brGEH+BiTjl0Sw9UgiL97Z\nnn
 HXtjD+bKOtPl6Oh4rmmFU3pcO7Yutxpn6zm4Y1fVg8tgftGphgBaOjsc2pC/DccfA2YQPrZCxW\nxX/X7WPOX4fp08qPj4d2o1Y1NxmlKwrbBgmkE1RKzqZkMX5xBDtPJvPCne0Yf62bhL388DRstVlM\nItpwCKsjY3nuy520rFuNhaNNstjIFtu246WzUMn4GSXM1jECiEvKZNTC/By7s4Z05e4ujfQ26crk\nZcMb9QqXmaztMJXDm5Nn5dXv9rB8y3GubVOHD4d0dZ/pxdJg2yjVC4CHN+tji8FJycplyooo/th/\njhG9m/Ny/wBz71d/JYqKxxz7KzQN1scek7L3VApjw8I5n5HL7OHdubWDm+zOaNtuDJwHnR/QxxY3\nQinF9F8PMuu3g1zTug6fDO/GVd7mGPH6lwM/wfIHC5eZzJkxE3tPpTBq4VYysi0sGtODPq0MnmN3\n9nVwakfBsV9reCRSP3vKiGkc3rOpWTy8dBsRx84z4fpWPH2bB8brzr8VTthkWpFGqViOxKczblF+\nCqk37u3I8F7N9TbJeciorkP4be8ZpqyIosaFnMxusU1wzK+w9L7CZaINh5CTZ+W5L3eyJuokD3Rv\nwpsDOpkv7MW27bhlGvSdoo8tHsCmmHhCl0RStUpFvpjY2/gz1Lb6eCEOKptz0a4pHN6o4/kLjVIy\n8/hwSFf+Y/Shf0dT1MhdjxC48z197DEBGw7GM2n5NipouF8KqUuxWuB1mx3zJoVD3bb62GNSlFLM\n33CEN3/YS8dGNZk3Moj67pCT2fZldfVdMGS5Pra4GckZuUxYGsnmwwk8cUtbHrmxtbnCXop6r0hH\nyKl8s/0kT32xgxZ1qhE2ugeNjBz2UtS7xeT6MLzDuyr8BC99vZv6Nauw5uE+5thxxJHIyF2pUEqx\nePMxXl8bTeu61Zk7IohmflX1Nss5iDYcQq7Fyivf5odK3d6hAR8M6mL+bYLTzsH
 7rQuXiTYcxonE\nDEaHhXMsIZ3pg7owoGuTkj9kJD4KhvgDhctEH05DKcXcvw/z1g/76NmiNnNGBFHTx8BhL6tGQPQ3\nhcvcQB+GbdVz8qxMWxvNkn+OcU3r/Hhdt15oZEtcFMy5oXCZjrlTzUBOXr7jsmLrcW5uX58ZgwOp\nXsWwEi87uVnwpk2qo8f3QE2TvXQNQHJmLpOWbWNDTDwTb2jF07e6wTbB0hFyKttPJDFuUTi5lvwN\nSHq1NNnska0+pkRB7Zb62OIBXLrb3l2dG/LBg12oUsnAOXZt9fHMEahau+hzTYYhvYFzqdk8vCyS\n8KPnCbmuJc/cdjWV3HWhUVHIC6vUJKRlM3HpNrYeTeThCzmZTe+4FIVo

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/python/setup.py.in
----------------------------------------------------------------------
diff --git a/python/setup.py.in b/python/setup.py.in
index 97ea2ca..f667ae5 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -70,6 +70,7 @@ setup(
 	'xmlrunner',
 	'tqdm',
 	'ipywidgets',
+	'matplotlib',
         ],
 
     #List additional groups of dependencies here (e.g. development



[07/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/doc/en/docs/notebook/model.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/model.ipynb b/doc/en/docs/notebook/model.ipynb
index 23a5553..6888435 100644
--- a/doc/en/docs/notebook/model.ipynb
+++ b/doc/en/docs/notebook/model.ipynb
@@ -29,7 +29,7 @@
    "cell_type": "code",
    "execution_count": 1,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -50,7 +50,7 @@
    "cell_type": "code",
    "execution_count": 2,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -67,9 +67,7 @@
   {
    "cell_type": "code",
    "execution_count": 3,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -83,14 +81,14 @@
     "dense = Dense('dense', 3, input_sample_shape=(2,))\n",
     "#dense.param_names()\n",
     "w, b = dense.param_values()\n",
-    "print w.shape, b.shape"
+    "print(w.shape, b.shape)"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 4,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -101,15 +99,13 @@
   {
    "cell_type": "code",
    "execution_count": 5,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
        "array([[ 0.02440065, -0.03396009,  0.01396658],\n",
-       "       [ 0.00771775,  0.07841966, -0.05931653]], dtype=float32)"
+       "       [ 0.00771775,  0.07841966, -0.05931654]], dtype=float32)"
       ]
      },
      "execution_count": 5,
@@ -127,9 +123,7 @@
   {
    "cell_type": "code",
    "execution_count": 6,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -141,7 +135,7 @@
    ],
    "source": [
     "gx, [gw, gb] = dense.backward(True, y)\n",
-    "print gx.shape, gw.shape, gb.shape"
+    "print(gx.shape, gw.shape, gb.shape)"
    ]
   },
   {
@@ -154,9 +148,7 @@
   {
    "cell_type": "code",
    "execution_count": 7,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -168,7 +160,7 @@
    ],
    "source": [
     "conv = Conv2D('conv', 4, 3, 1, input_sample_shape=(3, 6, 6))\n",
-    "print conv.get_output_sample_shape()"
+    "print(conv.get_output_sample_shape())"
    ]
   },
   {
@@ -181,9 +173,7 @@
   {
    "cell_type": "code",
    "execution_count": 8,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -195,7 +185,7 @@
    ],
    "source": [
     "pool = MaxPooling2D('pool', 3, 2, input_sample_shape=(4, 6, 6))\n",
-    "print pool.get_output_sample_shape()"
+    "print(pool.get_output_sample_shape())"
    ]
   },
   {
@@ -219,9 +209,7 @@
   {
    "cell_type": "code",
    "execution_count": 10,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -233,15 +221,13 @@
    ],
    "source": [
     "split = Split('split', 2, input_sample_shape=(4, 6, 6))\n",
-    "print split.get_output_sample_shape()"
+    "print(split.get_output_sample_shape())"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 11,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -253,15 +239,13 @@
    ],
    "source": [
     "merge = Merge('merge', input_sample_shape=(4, 6, 6))\n",
-    "print merge.get_output_sample_shape()"
+    "print(merge.get_output_sample_shape())"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 12,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -273,15 +257,13 @@
    ],
    "source": [
     "sli = Slice('slice', 1, [2], input_sample_shape=(4, 6, 6))\n",
-    "print sli.get_output_sample_shape()"
+    "print(sli.get_output_sample_shape())"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 13,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -293,7 +275,7 @@
    ],
    "source": [
     "concat = Concat('concat', 1, input_sample_shapes=[(3, 6, 6), (1, 6, 6)])\n",
-    "print concat.get_output_sample_shape()"
+    "print(concat.get_output_sample_shape())"
    ]
   },
   {
@@ -306,9 +288,7 @@
   {
    "cell_type": "code",
    "execution_count": 14,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -328,26 +308,24 @@
     "x = tensor.Tensor((3, 5))\n",
     "x.uniform(0, 1)  # randomly genearte the prediction activation\n",
     "x = tensor.softmax(x)  # normalize the prediction into probabilities\n",
-    "print tensor.to_numpy(x)\n",
+    "print(tensor.to_numpy(x))\n",
     "y = tensor.from_numpy(np.array([0, 1, 3], dtype=np.int))  # set the truth\n",
     "\n",
     "f = metric.Accuracy()\n",
     "acc = f.evaluate(x, y)  # averaged accuracy over all 3 samples in x\n",
-    "print acc"
+    "print(acc)"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 15,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "1.80309379101\n",
+      "1.8030937910079956\n",
       "[[-0.78104687  0.18748793  0.16346708  0.24803984  0.18205206]\n",
       " [ 0.21501946 -0.83683592  0.19003348  0.20714596  0.22463693]\n",
       " [ 0.20000091  0.23285127  0.26842937 -0.87474263  0.17346108]]\n"
@@ -364,8 +342,8 @@
     "f = loss.SoftmaxCrossEntropy()\n",
     "l = f.forward(True, x, y)  # l is tensor with 3 loss values\n",
     "g = f.backward()  # g is a tensor containing all gradients of x w.r.t l\n",
-    "print l.l1()\n",
-    "print tensor.to_numpy(g)"
+    "print(l.l1())\n",
+    "print(tensor.to_numpy(g))"
    ]
   },
   {
@@ -378,14 +356,12 @@
   {
    "cell_type": "code",
    "execution_count": 16,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "<singa.tensor.Tensor at 0x7f6a0c7cfe90>"
+       "<singa.tensor.Tensor at 0x7f539260f710>"
       ]
      },
      "execution_count": 16,
@@ -416,20 +392,18 @@
   {
    "cell_type": "code",
    "execution_count": 17,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "conv1 (32, 32, 32)\n",
-      "relu1 (32, 32, 32)\n",
-      "pool1 (32, 16, 16)\n",
-      "flat (8192,)\n",
-      "dense (10,)\n",
-      "[u'conv1_weight', u'conv1_bias', u'dense_weight', u'dense_bias']\n"
+      "('conv1', (32, 32, 32))\n",
+      "('relu1', (32, 32, 32))\n",
+      "('pool1', (32, 16, 16))\n",
+      "('flat', (8192,))\n",
+      "('dense', (10,))\n",
+      "['conv1/weight', 'conv1/bias', 'dense/weight', 'dense/bias']\n"
      ]
     }
    ],
@@ -449,25 +423,23 @@
     "        p.set_value(0)\n",
     "    else:\n",
     "        p.gaussian(0, 0.01)\n",
-    "print net.param_names()"
+    "print(net.param_names())"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 18,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "conv1 (32, 32, 32)\n",
-      "relu1 (32, 32, 32)\n",
-      "pool1 (32, 16, 16)\n",
-      "flat (8192,)\n",
-      "dense (10,)\n"
+      "('conv1', (32, 32, 32))\n",
+      "('relu1', (32, 32, 32))\n",
+      "('pool1', (32, 16, 16))\n",
+      "('flat', (8192,))\n",
+      "('dense', (10,))\n"
      ]
     }
    ],
@@ -514,21 +486,21 @@
  "metadata": {
   "anaconda-cloud": {},
   "kernelspec": {
-   "display_name": "Python [conda env:conda]",
+   "display_name": "py3",
    "language": "python",
-   "name": "conda-env-conda-py"
+   "name": "py3"
   },
   "language_info": {
    "codemirror_mode": {
     "name": "ipython",
-    "version": 2
+    "version": 3
    },
    "file_extension": ".py",
    "mimetype": "text/x-python",
    "name": "python",
    "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython2",
-   "version": "2.7.13"
+   "pygments_lexer": "ipython3",
+   "version": "3.5.3"
   }
  },
  "nbformat": 4,


[02/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/c94b3dfd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/c94b3dfd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/c94b3dfd

Branch: refs/heads/master
Commit: c94b3dfd273994ecd17d361558b8e019c1cf3ed3
Parents: 14f0d8c
Author: Moaz Reyad <mo...@gmail.com>
Authored: Wed May 31 13:34:26 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:15:59 2017 +0800

----------------------------------------------------------------------
 cmake/Dependencies.cmake             |  3 +-
 doc/en/docs/notebook/utils.py        |  6 +++-
 examples/caffe/predict.py            |  9 ++++--
 examples/char-rnn/sample.py          | 12 ++++++--
 examples/char-rnn/train.py           | 46 ++++++++++++++++++-------------
 examples/cifar10/alexnet.py          |  4 ++-
 examples/cifar10/caffe/caffe_net.py  | 12 +++++---
 examples/cifar10/download_data.py    | 19 +++++++------
 examples/cifar10/predict.py          | 10 +++++--
 examples/cifar10/resnet.py           |  8 ++++--
 examples/cifar10/train.py            | 40 ++++++++++++++++-----------
 examples/cifar10/vgg.py              |  8 ++++--
 examples/imagenet/googlenet/serve.py | 15 ++++++----
 examples/imagenet/resnet/convert.py  |  3 +-
 examples/imagenet/resnet/model.py    |  5 +++-
 examples/imagenet/resnet/serve.py    | 25 ++++++++++-------
 examples/mnist/train.py              | 32 ++++++++++++---------
 python/CMakeLists.txt                |  9 +++++-
 python/rafiki/agent.py               | 10 ++++---
 python/singa/layer.py                |  9 +++---
 python/singa/loss.py                 |  2 +-
 python/singa/optimizer.py            | 19 ++++++-------
 python/singa/snapshot.py             |  4 +--
 python/singa/tensor.py               | 17 +++++++++++-
 src/api/model_layer.i                |  1 +
 src/api/model_optimizer.i            |  1 +
 test/python/test_layer.py            |  1 +
 test/python/test_loss.py             |  4 ++-
 test/python/test_metric.py           |  8 ++++--
 test/python/test_net.py              |  5 +++-
 test/python/test_optimizer.py        |  8 ++++--
 test/python/test_tensor.py           |  4 ++-
 tool/debian/postinst                 |  2 +-
 tool/opencl/clsrc_to_str.py          |  2 +-
 34 files changed, 233 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/cmake/Dependencies.cmake
----------------------------------------------------------------------
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
index aa3c090..180732b 100644
--- a/cmake/Dependencies.cmake
+++ b/cmake/Dependencies.cmake
@@ -127,11 +127,12 @@ IF(USE_PYTHON)
     IF(PYTHON2)
         FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
         FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
+	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
     ELSE()
         FIND_PACKAGE(PythonLibs 3.0 REQUIRED)
         FIND_PACKAGE(PythonInterp 3.0 REQUIRED)
+	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
     ENDIF()
-    FIND_PACKAGE(SWIG 3.0 REQUIRED)
 ENDIF()
 
 IF(USE_JAVA)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/doc/en/docs/notebook/utils.py
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/utils.py b/doc/en/docs/notebook/utils.py
index ff772ad..3af9ec5 100755
--- a/doc/en/docs/notebook/utils.py
+++ b/doc/en/docs/notebook/utils.py
@@ -5,6 +5,10 @@ processing the outputs into a more understandable way.
 For example ``tile_raster_images`` helps in generating a easy to grasp
 image from a set of samples or weights.
 """
+from __future__ import division
+from builtins import zip
+from builtins import range
+from past.utils import old_div
 
 import numpy
 
@@ -13,7 +17,7 @@ def scale_to_unit_interval(ndar, eps=1e-8):
     """ Scales all values in the ndarray ndar to be between 0 and 1 """
     ndar = ndar.copy()
     ndar -= ndar.min()
-    ndar *= 1.0 / (ndar.max() + eps)
+    ndar *= old_div(1.0, (ndar.max() + eps))
     return ndar
 
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/caffe/predict.py
----------------------------------------------------------------------
diff --git a/examples/caffe/predict.py b/examples/caffe/predict.py
index 663cd87..62e6a86 100644
--- a/examples/caffe/predict.py
+++ b/examples/caffe/predict.py
@@ -1,3 +1,6 @@
+from __future__ import print_function
+from builtins import input
+from builtins import range
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -69,11 +72,11 @@ def predict(net, dev, synset_list, topk=5):
         topk, return the topk labels for each image.
     '''
     while True:
-        img_path = raw_input("Enter input image path('quit' to exit): ")
+        img_path = eval(input("Enter input image path('quit' to exit): "))
         if img_path == 'quit':
             return
         if not os.path.exists(img_path):
-            print 'Path is invalid'
+            print('Path is invalid')
             continue
         img = read_image(img_path)
         x = tensor.from_numpy(img.astype(np.float32)[np.newaxis,:])
@@ -82,7 +85,7 @@ def predict(net, dev, synset_list, topk=5):
         y.to_host()
         prob = tensor.to_numpy(y)
         lbl = np.argsort(-prob[0])  # sort prob in descending order
-        print [synset_list[lbl[i]] for i in range(topk)]
+        print([synset_list[lbl[i]] for i in range(topk)])
 
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/char-rnn/sample.py
----------------------------------------------------------------------
diff --git a/examples/char-rnn/sample.py b/examples/char-rnn/sample.py
index 9b6e757..5b0b66a 100644
--- a/examples/char-rnn/sample.py
+++ b/examples/char-rnn/sample.py
@@ -15,8 +15,14 @@
 # limitations under the License.
 # =============================================================================
 '''Sample characters from the pre-trained model'''
+from __future__ import division
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import range
+from past.utils import old_div
 import sys
-import cPickle as pickle
+import pickle as pickle
 import numpy as np
 import argparse
 
@@ -69,7 +75,7 @@ def sample(model_path, nsamples=100, seed_text='', do_sample=True):
         sys.stdout.write(seed_text)
     else:
         y = tensor.Tensor((1, vocab_size), cuda)
-        y.set_value(1.0 / vocab_size)
+        y.set_value(old_div(1.0, vocab_size))
 
     for i in range(nsamples):
         y.to_host()
@@ -89,7 +95,7 @@ def sample(model_path, nsamples=100, seed_text='', do_sample=True):
         y = tensor.softmax(y)
         hx = outputs[1]
         cx = outputs[2]
-    print ''
+    print('')
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='sample chars from char-rnn')

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/char-rnn/train.py
----------------------------------------------------------------------
diff --git a/examples/char-rnn/train.py b/examples/char-rnn/train.py
index d28646e..0eeeb35 100644
--- a/examples/char-rnn/train.py
+++ b/examples/char-rnn/train.py
@@ -19,7 +19,15 @@ The model is created following https://github.com/karpathy/char-rnn
 The train file could be any text file,
 e.g., http://cs.stanford.edu/people/karpathy/char-rnn/
 '''
-import cPickle as pickle
+from __future__ import division
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import zip
+from builtins import range
+from builtins import object
+from past.utils import old_div
+import pickle as pickle
 import numpy as np
 import argparse
 
@@ -51,18 +59,18 @@ class Data(object):
         self.idx_to_char = {i: ch for i, ch in enumerate(chars)}
         data = [self.char_to_idx[c] for c in self.raw_data]
         # seq_length + 1 for the data + label
-        nsamples = len(data) / (1 + seq_length)
+        nsamples = old_div(len(data), (1 + seq_length))
         data = data[0:nsamples * (1 + seq_length)]
         data = np.asarray(data, dtype=np.int32)
         data = np.reshape(data, (-1, seq_length + 1))
         # shuffle all sequences
         np.random.shuffle(data)
         self.train_dat = data[0:int(data.shape[0]*train_ratio)]
-        self.num_train_batch = self.train_dat.shape[0] / batch_size
+        self.num_train_batch = old_div(self.train_dat.shape[0], batch_size)
         self.val_dat = data[self.train_dat.shape[0]:]
-        self.num_test_batch = self.val_dat.shape[0] / batch_size
-        print 'train dat', self.train_dat.shape
-        print 'val dat', self.val_dat.shape
+        self.num_test_batch = old_div(self.val_dat.shape[0], batch_size)
+        print('train dat', self.train_dat.shape)
+        print('val dat', self.val_dat.shape)
 
 
 def numpy2tensors(npx, npy, dev):
@@ -94,7 +102,7 @@ def convert(batch, batch_size, seq_length, vocab_size, dev):
 
 
 def get_lr(epoch):
-    return 0.001 / float(1 << (epoch / 50))
+    return old_div(0.001, float(1 << (old_div(epoch, 50))))
 
 
 def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
@@ -111,10 +119,10 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
             data.vocab_size,
         ))
     rnn.to_device(cuda)
-    print 'created rnn'
+    print('created rnn')
     rnn_w = rnn.param_values()[0]
     rnn_w.uniform(-0.08, 0.08)  # init all rnn parameters
-    print 'rnn weight l1 = %f' % (rnn_w.l1())
+    print('rnn weight l1 = %f' % (rnn_w.l1()))
     dense = layer.Dense(
         'dense',
         data.vocab_size,
@@ -124,12 +132,12 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
     dense.to_device(cuda)
     dense_w = dense.param_values()[0]
     dense_b = dense.param_values()[1]
-    print 'dense w ', dense_w.shape
-    print 'dense b ', dense_b.shape
+    print('dense w ', dense_w.shape)
+    print('dense b ', dense_b.shape)
     initializer.uniform(dense_w, dense_w.shape[0], 0)
-    print 'dense weight l1 = %f' % (dense_w.l1())
+    print('dense weight l1 = %f' % (dense_w.l1()))
     dense_b.set_value(0)
-    print 'dense b l1 = %f' % (dense_b.l1())
+    print('dense b l1 = %f' % (dense_b.l1()))
 
     g_dense_w = tensor.Tensor(dense_w.shape, cuda)
     g_dense_b = tensor.Tensor(dense_b.shape, cuda)
@@ -162,7 +170,7 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
                 # print output.l1(), act.l1()
             utils.update_progress(
                 b * 1.0 / data.num_train_batch, 'training loss = %f' %
-                (batch_loss / seq_length))
+                (old_div(batch_loss, seq_length)))
             train_loss += batch_loss
 
             grads.append(tensor.Tensor())
@@ -176,8 +184,8 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
             opt.apply_with_lr(
                 epoch, get_lr(epoch),
                 g_dense_b, dense_b, 'dense_b')
-        print '\nEpoch %d, train loss is %f' % \
-            (epoch, train_loss / data.num_train_batch / seq_length)
+        print('\nEpoch %d, train loss is %f' % \
+            (epoch, train_loss / data.num_train_batch / seq_length))
 
         eval_loss = 0
         for b in range(data.num_test_batch):
@@ -191,13 +199,13 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
                 output = dense.forward(model_pb2.kEval, output)
                 eval_loss += lossfun.forward(model_pb2.kEval,
                                              output, label).l1()
-        print 'Epoch %d, evaluation loss is %f' % \
-            (epoch, eval_loss / data.num_test_batch / seq_length)
+        print('Epoch %d, evaluation loss is %f' % \
+            (epoch, eval_loss / data.num_test_batch / seq_length))
 
         if (epoch + 1) % 30 == 0:
             # checkpoint the file model
             with open('%s_%d.bin' % (model_path, epoch), 'wb') as fd:
-                print 'saving model to %s' % model_path
+                print('saving model to %s' % model_path)
                 d = {}
                 for name, w in zip(
                         ['rnn_w', 'dense_w', 'dense_b'],

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/alexnet.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/alexnet.py b/examples/cifar10/alexnet.py
index 02437b3..b056e70 100644
--- a/examples/cifar10/alexnet.py
+++ b/examples/cifar10/alexnet.py
@@ -19,6 +19,8 @@ https://code.google.com/p/cuda-convnet/source/browse/trunk/example-layers/layers
 Following the same setting for hyper-parameters and data pre-processing, the final
 validation accuracy would be about 82%.
 '''
+from __future__ import print_function
+from builtins import zip
 
 # sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
 from singa import layer
@@ -56,6 +58,6 @@ def create_net(use_cpu=False):
             p.gaussian(filler.mean, filler.std)
         else:
             p.set_value(0)
-        print specs.name, filler.type, p.l1()
+        print(specs.name, filler.type, p.l1())
 
     return net

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/caffe/caffe_net.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/caffe/caffe_net.py b/examples/cifar10/caffe/caffe_net.py
index 2db131a..dd1eb7d 100644
--- a/examples/cifar10/caffe/caffe_net.py
+++ b/examples/cifar10/caffe/caffe_net.py
@@ -1,3 +1,7 @@
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import zip
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -14,13 +18,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # =============================================================================
-import urllib
+import urllib.request, urllib.parse, urllib.error
 from singa import converter
 
 
 def create_net(use_cpu):
-    urllib.urlretrieve("https://raw.githubusercontent.com/BVLC/caffe/master/examples/cifar10/cifar10_full_train_test.prototxt", "train_test.prototxt")
-    urllib.urlretrieve("https://raw.githubusercontent.com/BVLC/caffe/master/examples/cifar10/cifar10_full_solver.prototxt", "solver.prototxt")
+    urllib.request.urlretrieve("https://raw.githubusercontent.com/BVLC/caffe/master/examples/cifar10/cifar10_full_train_test.prototxt", "train_test.prototxt")
+    urllib.request.urlretrieve("https://raw.githubusercontent.com/BVLC/caffe/master/examples/cifar10/cifar10_full_solver.prototxt", "solver.prototxt")
     input_sample_shape = [3, 32, 32, ]
 
     cvt = converter.CaffeConverter("train_test.prototxt", "solver.prototxt",
@@ -32,6 +36,6 @@ def create_net(use_cpu):
             p.gaussian(filler.mean, filler.std)
         else:
             p.set_value(0)
-        print specs.name, filler.type, p.l1()
+        print(specs.name, filler.type, p.l1())
 
     return net

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/download_data.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/download_data.py b/examples/cifar10/download_data.py
index 7129b03..a0b73c5 100755
--- a/examples/cifar10/download_data.py
+++ b/examples/cifar10/download_data.py
@@ -17,7 +17,10 @@
 # limitations under the License.
 # 
 
-import urllib
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+import urllib.request, urllib.parse, urllib.error
 import tarfile
 import os
 import sys
@@ -26,17 +29,17 @@ import argparse
 
 def extract_tarfile(filepath):
     if os.path.exists(filepath):
-        print 'The tar file does exist. Extracting it now..'
+        print('The tar file does exist. Extracting it now..')
         with tarfile.open(filepath, 'r') as f:
             f.extractall('.')
-        print 'Finished!'
+        print('Finished!')
         sys.exit(0)
 
 
 def check_dir_exist(dirpath):
     if os.path.exists(dirpath):
-        print 'Directory %s does exist. To redownload the files, '\
-            'remove the existing directory and %s.tar.gz' % (dirpath, dirpath)
+        print('Directory %s does exist. To redownload the files, '\
+            'remove the existing directory and %s.tar.gz' % (dirpath, dirpath))
         return True
     else:
         return False
@@ -45,10 +48,10 @@ def check_dir_exist(dirpath):
 def do_download(dirpath, gzfile, url):
     if check_dir_exist(dirpath):
         sys.exit(0)
-    print 'Downloading CIFAR10 from %s' % (url)
-    urllib.urlretrieve(url, gzfile)
+    print('Downloading CIFAR10 from %s' % (url))
+    urllib.request.urlretrieve(url, gzfile)
     extract_tarfile(gzfile)
-    print 'Finished!'
+    print('Finished!')
 
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/predict.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/predict.py b/examples/cifar10/predict.py
index dca44fe..123818a 100644
--- a/examples/cifar10/predict.py
+++ b/examples/cifar10/predict.py
@@ -15,7 +15,11 @@
 # limitations under the License.
 # =============================================================================
 '''Predicting the labels for new images using the pre-trained alexnet model'''
-import cPickle as pickle
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import range
+import pickle as pickle
 import numpy as np
 
 # sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
@@ -46,7 +50,7 @@ def predict(net, images, dev, topk=5):
 
 
 def load_dataset(filepath):
-    print 'Loading data file %s' % filepath
+    print('Loading data file %s' % filepath)
     with open(filepath, 'rb') as fd:
         cifar10 = pickle.load(fd)
     image = cifar10['data'].astype(dtype=np.uint8)
@@ -88,4 +92,4 @@ if __name__ == '__main__':
     mean = compute_image_mean('cifar-10-batches-py')
     test_images, _ = load_test_data('cifar-10-batches-py')
     # predict for two images
-    print predict(model, test_images[0:2] - mean, dev)
+    print(predict(model, test_images[0:2] - mean, dev))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/resnet.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/resnet.py b/examples/cifar10/resnet.py
index 6b573e9..4b9bad0 100644
--- a/examples/cifar10/resnet.py
+++ b/examples/cifar10/resnet.py
@@ -19,8 +19,12 @@ The best validation accuracy we achieved is about 83% without data augmentation.
 The performance could be improved by tuning some hyper-parameters, including
 learning rate, weight decay, max_epoch, parameter initialization, etc.
 """
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import zip
 
-import cPickle as pickle
+import pickle as pickle
 
 # sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
 # use the python modules by installing py singa in build/python
@@ -73,7 +77,7 @@ def create_net(use_cpu=False):
     net.add(layer.AvgPooling2D("pool4", 8, 8, border_mode='valid'))
     net.add(layer.Flatten('flat'))
     net.add(layer.Dense('ip5', 10))
-    print 'Start intialization............'
+    print('Start intialization............')
     for (p, name) in zip(net.param_values(), net.param_names()):
         # print name, p.shape
         if 'mean' in name or 'beta' in name:

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/train.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/train.py b/examples/cifar10/train.py
index d54d694..8204055 100644
--- a/examples/cifar10/train.py
+++ b/examples/cifar10/train.py
@@ -18,8 +18,16 @@
 It includes 5 binary dataset, each contains 10000 images. 1 row (1 image)
 includes 1 label & 3072 pixels.  3072 pixels are 3 channels of a 32x32 image
 """
-
-import cPickle
+from __future__ import division
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import zip
+from builtins import str
+from builtins import range
+from past.utils import old_div
+
+import pickle
 import numpy as np
 import os
 import argparse
@@ -38,9 +46,9 @@ import resnet
 
 
 def load_dataset(filepath):
-    print 'Loading data file %s' % filepath
+    print('Loading data file %s' % filepath)
     with open(filepath, 'rb') as fd:
-        cifar10 = cPickle.load(fd)
+        cifar10 = pickle.load(fd)
     image = cifar10['data'].astype(dtype=np.uint8)
     image = image.reshape((-1, 3, 32, 32))
     label = np.asarray(cifar10['labels'], dtype=np.uint8)
@@ -85,7 +93,7 @@ def normalize_for_alexnet(train_x, test_x):
 
 
 def vgg_lr(epoch):
-    return 0.1 / float(1 << ((epoch / 25)))
+    return old_div(0.1, float(1 << ((old_div(epoch, 25)))))
 
 
 def alexnet_lr(epoch):
@@ -115,12 +123,12 @@ def caffe_lr(epoch):
 
 def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
           use_cpu=False):
-    print 'Start intialization............'
+    print('Start intialization............')
     if use_cpu:
-        print 'Using CPU'
+        print('Using CPU')
         dev = device.get_default_device()
     else:
-        print 'Using GPU'
+        print('Using GPU')
         dev = device.create_cuda_gpu()
 
     net.to_device(dev)
@@ -131,13 +139,13 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
     tx = tensor.Tensor((batch_size, 3, 32, 32), dev)
     ty = tensor.Tensor((batch_size,), dev, core_pb2.kInt)
     train_x, train_y, test_x, test_y = data
-    num_train_batch = train_x.shape[0] / batch_size
-    num_test_batch = test_x.shape[0] / batch_size
+    num_train_batch = old_div(train_x.shape[0], batch_size)
+    num_test_batch = old_div(test_x.shape[0], batch_size)
     idx = np.arange(train_x.shape[0], dtype=np.int32)
     for epoch in range(max_epoch):
         np.random.shuffle(idx)
         loss, acc = 0.0, 0.0
-        print 'Epoch %d' % epoch
+        print('Epoch %d' % epoch)
         for b in range(num_train_batch):
             x = train_x[idx[b * batch_size: (b + 1) * batch_size]]
             y = train_y[idx[b * batch_size: (b + 1) * batch_size]]
@@ -152,8 +160,8 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
             utils.update_progress(b * 1.0 / num_train_batch,
                                   'training loss = %f, accuracy = %f' % (l, a))
         info = '\ntraining loss = %f, training accuracy = %f, lr = %f' \
-            % (loss / num_train_batch, acc / num_train_batch, get_lr(epoch))
-        print info
+            % (old_div(loss, num_train_batch), old_div(acc, num_train_batch), get_lr(epoch))
+        print(info)
 
         loss, acc = 0.0, 0.0
         for b in range(num_test_batch):
@@ -165,8 +173,8 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
             loss += l
             acc += a
 
-        print 'test loss = %f, test accuracy = %f' \
-            % (loss / num_test_batch, acc / num_test_batch)
+        print('test loss = %f, test accuracy = %f' \
+            % (old_div(loss, num_test_batch), old_div(acc, num_test_batch)))
     net.save('model', 20)  # save model params into checkpoint file
 
 if __name__ == '__main__':
@@ -178,7 +186,7 @@ if __name__ == '__main__':
     args = parser.parse_args()
     assert os.path.exists(args.data), \
         'Pls download the cifar10 dataset via "download_data.py py"'
-    print 'Loading data ..................'
+    print('Loading data ..................')
     train_x, train_y = load_train_data(args.data)
     test_x, test_y = load_test_data(args.data)
     if args.model == 'caffe':

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/cifar10/vgg.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/vgg.py b/examples/cifar10/vgg.py
index ce0c210..ec893a9 100644
--- a/examples/cifar10/vgg.py
+++ b/examples/cifar10/vgg.py
@@ -19,6 +19,8 @@ The best validation accuracy we achieved is about 89% without data augmentation.
 The performance could be improved by tuning some hyper-parameters, including
 learning rate, weight decay, max_epoch, parameter initialization, etc.
 """
+from __future__ import print_function
+from builtins import zip
 
 # sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
 
@@ -74,9 +76,9 @@ def create_net(use_cpu=False):
     net.add(layer.Activation('relu_ip1'))
     net.add(layer.Dropout('drop_ip2', 0.5))
     net.add(layer.Dense('ip2', 10))
-    print 'Start intialization............'
+    print('Start intialization............')
     for (p, name) in zip(net.param_values(), net.param_names()):
-        print name, p.shape
+        print(name, p.shape)
         if 'mean' in name or 'beta' in name:
             p.set_value(0.0)
         elif 'var' in name:
@@ -90,6 +92,6 @@ def create_net(use_cpu=False):
                 p.gaussian(0, 0.02)
         else:
             p.set_value(0)
-        print name, p.l1()
+        print(name, p.l1())
 
     return net

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/imagenet/googlenet/serve.py
----------------------------------------------------------------------
diff --git a/examples/imagenet/googlenet/serve.py b/examples/imagenet/googlenet/serve.py
index aee890d..308acd6 100644
--- a/examples/imagenet/googlenet/serve.py
+++ b/examples/imagenet/googlenet/serve.py
@@ -17,6 +17,9 @@
 ''' This model is created following Caffe implementation of GoogleNet
 https://github.com/BVLC/caffe/blob/master/models/bvlc_googlenet/
 '''
+from __future__ import print_function
+from builtins import zip
+from builtins import str
 import os
 import sys
 import time
@@ -157,14 +160,14 @@ def serve(agent, use_cpu, parameter_file, topk=5):
         dev = device.get_default_device()
         layer.engine = 'singacpp'
     else:
-        print "runing with gpu"
+        print("runing with gpu")
         dev = device.create_cuda_gpu()
     agent = agent
 
-    print 'Start intialization............'
+    print('Start intialization............')
     net = create_net((3, 224, 224), parameter_file)
     net.to_device(dev)
-    print 'End intialization............'
+    print('End intialization............')
 
     labels = np.loadtxt('synset_words.txt', str, delimiter='\t ')
     while True:
@@ -199,15 +202,15 @@ def serve(agent, use_cpu, parameter_file, topk=5):
                 response = "Sorry, system error during prediction."
             agent.push(MsgType.kResponse, response)
         elif MsgType.kCommandStop.equal(msg_type):
-                print 'get stop command'
+                print('get stop command')
                 agent.push(MsgType.kStatus, "success")
                 break
         else:
-            print 'get unsupported message %s' % str(msg_type)
+            print('get unsupported message %s' % str(msg_type))
             agent.push(MsgType.kStatus, "Unknown command")
             break
         # while loop
-    print "server stop"
+    print("server stop")
 
 
 def main():

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/imagenet/resnet/convert.py
----------------------------------------------------------------------
diff --git a/examples/imagenet/resnet/convert.py b/examples/imagenet/resnet/convert.py
index 042d2ec..7c98139 100644
--- a/examples/imagenet/resnet/convert.py
+++ b/examples/imagenet/resnet/convert.py
@@ -90,8 +90,7 @@ def traverse(m, idx, params, param_names):
 
 if __name__ == '__main__':
     parser = ArgumentParser(description='Convert params from torch to python '
-            'dict. \n resnet could have depth of 18, 34, 101, 152; \n
-            wrn has depth 50; preact has depth 200; addbn has depth 50')
+            'dict. \n resnet could have depth of 18, 34, 101, 152; \n wrn has depth 50; preact has depth 200; addbn has depth 50')
     parser.add_argument("infile", help="torch checkpoint file")
     parser.add_argument("model", choices = ['resnet', 'wrn', 'preact', 'addbn'])
     parser.add_argument("depth", type=int, choices = [18, 34, 50, 101, 152, 200])

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/imagenet/resnet/model.py
----------------------------------------------------------------------
diff --git a/examples/imagenet/resnet/model.py b/examples/imagenet/resnet/model.py
index bf90da3..6ab8741 100644
--- a/examples/imagenet/resnet/model.py
+++ b/examples/imagenet/resnet/model.py
@@ -17,6 +17,9 @@
 ''' This models are created following https://github.com/facebook/fb.resnet.torch.git
 and https://github.com/szagoruyko/wide-residual-networks
 '''
+from __future__ import print_function
+from builtins import zip
+from builtins import range
 from singa.layer import Conv2D, Activation, MaxPooling2D, AvgPooling2D,\
         Split, Merge, Flatten, Dense, BatchNormalization, Softmax
 from singa import net as ffnet
@@ -139,7 +142,7 @@ def stage(sid, net, num_blk, inplane, midplane, outplane, stride, block, preact=
 def init_params(net, weight_path=None):
     if weight_path == None:
         for pname, pval in zip(net.param_names(), net.param_values()):
-            print pname, pval.shape
+            print(pname, pval.shape)
             if 'conv' in pname and len(pval.shape) > 1:
                 initializer.gaussian(pval, 0, pval.shape[1])
             elif 'dense' in pname:

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/imagenet/resnet/serve.py
----------------------------------------------------------------------
diff --git a/examples/imagenet/resnet/serve.py b/examples/imagenet/resnet/serve.py
index ba5adb1..fde06fe 100644
--- a/examples/imagenet/resnet/serve.py
+++ b/examples/imagenet/resnet/serve.py
@@ -1,3 +1,8 @@
+from __future__ import division
+from __future__ import print_function
+from builtins import str
+from builtins import range
+from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -52,7 +57,7 @@ def predict(net, images, num=10):
     '''
     prob = net.predict(images)
     prob = tensor.to_numpy(prob)
-    prob = prob.reshape((images.shape[0] / num, num, -1))
+    prob = prob.reshape((old_div(images.shape[0], num), num, -1))
     prob = np.average(prob, 1)
     return prob
 
@@ -82,11 +87,11 @@ def serve(net, label_map, dev, agent, topk=5):
             try:
                 # process images
                 im = [np.array(x.convert('RGB'), dtype=np.float32).transpose(2, 0, 1) for x in image_transform(val['image'])]
-                im = np.array(im) / 256
+                im = old_div(np.array(im), 256)
                 im -= mean[np.newaxis, :, np.newaxis, np.newaxis]
                 im /= std[np.newaxis, :, np.newaxis, np.newaxis]
                 images.copy_from_numpy(im)
-                print "input: ", images.l1()
+                print("input: ", images.l1())
                 # do prediction
                 prob = predict(net, images, num_augmentation)[0]
                 idx = np.argsort(-prob)
@@ -100,17 +105,17 @@ def serve(net, label_map, dev, agent, topk=5):
             agent.push(MsgType.kResponse, response)
         elif msg.is_command():
             if MsgType.kCommandStop.equal(msg):
-                print 'get stop command'
+                print('get stop command')
                 agent.push(MsgType.kStatus, "success")
                 break
             else:
-                print 'get unsupported command %s' % str(msg)
+                print('get unsupported command %s' % str(msg))
                 agent.push(MsgType.kStatus, "Unknown command")
         else:
-            print 'get unsupported message %s' % str(msg)
+            print('get unsupported message %s' % str(msg))
             agent.push(MsgType.kStatus, "unsupported msg; going to shutdown")
             break
-    print "server stop"
+    print("server stop")
 
 def main():
     try:
@@ -133,14 +138,14 @@ def main():
 
         net = model.create_net(args.model, args.depth, args.use_cpu)
         if args.use_cpu:
-            print 'Using CPU'
+            print('Using CPU')
             dev = device.get_default_device()
         else:
-            print 'Using GPU'
+            print('Using GPU')
             dev = device.create_cuda_gpu()
             net.to_device(dev)
         model.init_params(net, args.parameter_file)
-        print 'Finish loading models'
+        print('Finish loading models')
 
         labels = np.loadtxt('synset_words.txt', str, delimiter='\t ')
         serve(net, labels, dev, agent)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/examples/mnist/train.py
----------------------------------------------------------------------
diff --git a/examples/mnist/train.py b/examples/mnist/train.py
index 0a00358..82d9a5a 100644
--- a/examples/mnist/train.py
+++ b/examples/mnist/train.py
@@ -1,3 +1,9 @@
+from __future__ import division
+from __future__ import print_function
+from future import standard_library
+standard_library.install_aliases()
+from builtins import range
+from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -19,7 +25,7 @@ import numpy as np
 import os
 import gzip
 import argparse
-import cPickle
+import pickle
 from singa import initializer
 from singa import utils
 from singa import optimizer
@@ -33,16 +39,16 @@ from singa.proto import core_pb2
 
 def load_train_data(file_path):
     f = gzip.open(file_path, 'rb')
-    train_set, valid_set, test_set = cPickle.load(f)
+    train_set, valid_set, test_set = pickle.load(f)
     traindata = train_set[0].astype(np.float32)
     validdata = valid_set[0].astype(np.float32)
-    print traindata.shape, validdata.shape
+    print(traindata.shape, validdata.shape)
     return traindata, validdata
 
 
 
 def train(data_file, use_gpu, num_epoch=10, batch_size=100):
-    print 'Start intialization............'
+    print('Start intialization............')
     lr = 0.1   # Learning rate
     weight_decay  = 0.0002
     hdim = 1000
@@ -55,7 +61,7 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
     thbias = tensor.from_numpy(np.zeros(hdim, dtype = np.float32))
     opt = optimizer.SGD(momentum=0.5, weight_decay=weight_decay)
 
-    print 'Loading data ..................'
+    print('Loading data ..................')
     train_x, valid_x = load_train_data(data_file)
 
     if use_gpu:
@@ -66,11 +72,11 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
     for t in [tweight, tvbias, thbias]:
         t.to_device(dev)
 
-    num_train_batch = train_x.shape[0] / batch_size
-    print "num_train_batch = %d " % (num_train_batch)
+    num_train_batch = old_div(train_x.shape[0], batch_size)
+    print("num_train_batch = %d " % (num_train_batch))
     for epoch in range(num_epoch):
         trainerrorsum = 0.0
-        print 'Epoch %d' % epoch
+        print('Epoch %d' % epoch)
         for b in range(num_train_batch):
             # positive phase
             tdata = tensor.from_numpy(
@@ -99,11 +105,11 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
             tgvbias = tensor.sum(tnegdata, 0) - tensor.sum(tdata, 0)
             tghbias = tensor.sum(tneghidprob, 0) - tensor.sum(tposhidprob, 0)
 
-            opt.apply_with_lr(epoch, lr / batch_size, tgweight, tweight, 'w')
-            opt.apply_with_lr(epoch, lr / batch_size, tgvbias, tvbias, 'vb')
-            opt.apply_with_lr(epoch, lr / batch_size, tghbias, thbias, 'hb')
+            opt.apply_with_lr(epoch, old_div(lr, batch_size), tgweight, tweight, 'w')
+            opt.apply_with_lr(epoch, old_div(lr, batch_size), tgvbias, tvbias, 'vb')
+            opt.apply_with_lr(epoch, old_div(lr, batch_size), tghbias, thbias, 'hb')
 
-        print 'training errorsum = %f' % (trainerrorsum)
+        print('training errorsum = %f' % (trainerrorsum))
 
         tvaliddata = tensor.from_numpy(valid_x)
         tvaliddata.to_device(dev)
@@ -119,7 +125,7 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
         tvalidnegdata = tensor.sigmoid(tvalidnegdata)
 
         validerrorsum = tensor.sum(tensor.square((tvaliddata - tvalidnegdata)))
-        print 'valid errorsum = %f' % (validerrorsum)
+        print('valid errorsum = %f' % (validerrorsum))
 
 
 if __name__ == '__main__':

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index 177326e..01396ff 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -93,8 +93,15 @@ PROTOBUF_GENERATE_PYTHON(proto_pys ${proto_files})
 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/singa/proto)
 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/python/rafiki)
 file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/src/api)
+
+IF(PYTHON2)
+	SET(SWIG_PYTHON3 "")
+ELSE()
+	SET(SWIG_PYTHON3 "-py3")
+ENDIF()
+
 execute_process(
-    COMMAND swig -c++ -python -I${CMAKE_SOURCE_DIR}/include
+    COMMAND swig -c++ -python ${SWIG_PYTHON3} -I${CMAKE_SOURCE_DIR}/include
     -outdir ${CMAKE_BINARY_DIR}/python/singa
     -o ${CMAKE_BINARY_DIR}/src/api/singa_wrap.cxx
     ${CMAKE_SOURCE_DIR}/src/api/singa.i)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/rafiki/agent.py
----------------------------------------------------------------------
diff --git a/python/rafiki/agent.py b/python/rafiki/agent.py
index d9e4e7a..98d9b01 100644
--- a/python/rafiki/agent.py
+++ b/python/rafiki/agent.py
@@ -1,3 +1,5 @@
+from builtins import str
+from builtins import object
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -25,7 +27,7 @@ from werkzeug.datastructures import CombinedMultiDict, MultiDict
 import pickle
 import uuid
 
-class MsgType:
+class MsgType(object):
    def __init__(self, name):
        self.name = name
    def __str__(self):
@@ -72,7 +74,7 @@ for t in types:
 app = Flask(__name__)
 top_k_=5
 
-class Agent():
+class Agent(object):
 
     def __init__(self,port):
         info_queue = Queue()
@@ -203,7 +205,7 @@ def failure(message):
 
 def transformFile(files):
     result= MultiDict([])
-    for f in files.keys():
+    for f in list(files.keys()):
         file = files[f]
         unique_filename = str(uuid.uuid4())+secure_filename(file.filename)
         filepath=os.path.join(os.getcwd(),unique_filename)
@@ -212,7 +214,7 @@ def transformFile(files):
     return result
 
 def deleteFiles(files):
-    for f in files.keys():
+    for f in list(files.keys()):
         filepath = files[f]    
         os.remove(filepath)
         #print "remove",filepath

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/singa/layer.py
----------------------------------------------------------------------
diff --git a/python/singa/layer.py b/python/singa/layer.py
index 2cdfe69..153768b 100644
--- a/python/singa/layer.py
+++ b/python/singa/layer.py
@@ -50,12 +50,11 @@ from __future__ import absolute_import
 from builtins import str
 from builtins import range
 from builtins import object
-from sets import Set
+from builtins import set
 from . import singa_wrap
 from .proto import model_pb2
 from . import tensor
 
-
 engine = 'cudnn'
 '''engine is the prefix of layer identifier.
 
@@ -1048,7 +1047,7 @@ class RNN(Layer):
         conf = self.conf.rnn_conf
         assert hidden_size > 0, 'Hidden feature size must > 0'
         conf.hidden_size = hidden_size
-        assert rnn_mode in Set(['lstm', 'gru', 'tanh', 'relu']),  \
+        assert rnn_mode in set(['lstm', 'gru', 'tanh', 'relu']),  \
             'rnn mode %s is not available' % (rnn_mode)
         conf.rnn_mode = rnn_mode
         conf.num_stacks = num_stacks
@@ -1164,7 +1163,7 @@ class GRU(RNN):
 
 
 def _check_engine(engine, allowed_engines):
-    assert engine.lower() in Set(allowed_engines), \
+    assert engine.lower() in set(allowed_engines), \
         '%s is not a supported engine. Pls use one of %s' % \
         (engine, ', '.join(allowed_engines))
 
@@ -1181,7 +1180,7 @@ def _create_layer(eng, layer):
     assert eng != 'cudnn' or cudnn_version > 0, 'CUDNN is not enabled, please '\
         'change the engine, e.g., layer.engine=singacpp'
     layer_type = eng + '_' + layer
-    return singa_wrap.CreateLayer(layer_type.lower())
+    return singa_wrap.CreateLayer(layer_type.lower().encode())
 
 
 def _set_kernel_stride_pad(conf, kernel, stride, border_mode, pad, in_shape):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/singa/loss.py
----------------------------------------------------------------------
diff --git a/python/singa/loss.py b/python/singa/loss.py
index d643218..800a113 100644
--- a/python/singa/loss.py
+++ b/python/singa/loss.py
@@ -41,7 +41,7 @@ from __future__ import absolute_import
 from past.utils import old_div
 from builtins import object
 from . import singa_wrap as singa
-from proto import model_pb2
+from .proto import model_pb2
 from . import tensor
 import numpy as np
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/singa/optimizer.py
----------------------------------------------------------------------
diff --git a/python/singa/optimizer.py b/python/singa/optimizer.py
index 8f1fe8e..54b81e8 100644
--- a/python/singa/optimizer.py
+++ b/python/singa/optimizer.py
@@ -39,8 +39,7 @@ from builtins import object
 import math
 from . import singa_wrap as singa
 from . import tensor
-from proto import model_pb2
-
+from .proto import model_pb2
 
 class Optimizer(object):
     '''The base python optimizer class.
@@ -205,7 +204,7 @@ class SGD(Optimizer):
         if self.momentum is not None:
             conf.momentum = self.momentum
         conf.type = 'sgd'
-        self.opt = singa.CreateOptimizer('SGD')
+        self.opt = singa.CreateOptimizer('SGD'.encode())
         self.opt.Setup(conf.SerializeToString())
 
     def apply_with_lr(self, epoch, lr, grad, value, name, step=-1):
@@ -214,7 +213,7 @@ class SGD(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr, name, grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor, value.singa_tensor)
         return value
 
 
@@ -232,7 +231,7 @@ class Nesterov(Optimizer):
         if self.momentum is not None:
             conf.momentum = momentum
         conf.type = 'nesterov'
-        self.opt = singa.CreateOptimizer('Nesterov')
+        self.opt = singa.CreateOptimizer('Nesterov'.encode())
         self.opt.Setup(conf.SerializeToString())
 
     def apply_with_lr(self, epoch, lr, grad, value, name, step=-1):
@@ -242,7 +241,7 @@ class Nesterov(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr, name, grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor, value.singa_tensor)
         return value
 
 
@@ -263,7 +262,7 @@ class RMSProp(Optimizer):
         conf = model_pb2.OptimizerConf()
         conf.rho = rho
         conf.delta = epsilon
-        self.opt = singa.CreateOptimizer('RMSProp')
+        self.opt = singa.CreateOptimizer('RMSProp'.encode())
         self.opt.Setup(conf.SerializeToString())
 
     def apply_with_lr(self, epoch, lr, grad, value, name, step=-1):
@@ -273,7 +272,7 @@ class RMSProp(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(step, lr,  name, grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(step, lr,  name.encode(), grad.singa_tensor, value.singa_tensor)
         return value
 
 
@@ -293,7 +292,7 @@ class AdaGrad(Optimizer):
         conf = model_pb2.OptimizerConf()
         conf.delta = epsilon
         conf.type = 'adagrad'
-        self.opt = singa.CreateOptimizer('AdaGrad')
+        self.opt = singa.CreateOptimizer('AdaGrad'.encode())
         self.opt.Setup(conf.SerializeToString())
 
     def apply_with_lr(self, epoch, lr, grad, value, name, step=-1):
@@ -303,7 +302,7 @@ class AdaGrad(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr,  name, grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr,  name.encode(), grad.singa_tensor, value.singa_tensor)
         return value
 
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/singa/snapshot.py
----------------------------------------------------------------------
diff --git a/python/singa/snapshot.py b/python/singa/snapshot.py
index 4c359fc..392ab3d 100644
--- a/python/singa/snapshot.py
+++ b/python/singa/snapshot.py
@@ -49,7 +49,7 @@ class Snapshot(object):
             mode (boolean): True for write, False for read
             buffer_size (int): Buffer size (in MB), default is 10
         '''
-        self.snapshot = singa.Snapshot(f, mode, buffer_size)
+        self.snapshot = singa.Snapshot(f.encode(), mode, buffer_size)
 
     def write(self, param_name, param_val):
         '''Call Write method to write a parameter
@@ -58,7 +58,7 @@ class Snapshot(object):
             param_name (string): name of the parameter
             param_val (Tensor): value tensor of the parameter
         '''
-        self.snapshot.Write(str(param_name), param_val.singa_tensor)
+        self.snapshot.Write(str(param_name).encode(), param_val.singa_tensor)
 
     def read(self):
         '''Call read method to load all (param_name, param_val)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/python/singa/tensor.py
----------------------------------------------------------------------
diff --git a/python/singa/tensor.py b/python/singa/tensor.py
index fabd84a..144ed61 100644
--- a/python/singa/tensor.py
+++ b/python/singa/tensor.py
@@ -423,6 +423,14 @@ class Tensor(object):
             return _call_singa_func(singa.DivFloat,
                                     self.singa_tensor, rhs)
 
+    def __truediv__(self, rhs):
+        if isinstance(rhs, Tensor):
+            return from_raw_tensor(
+                singa.__div__(self.singa_tensor, rhs.singa_tensor))
+        else:
+            return _call_singa_func(singa.DivFloat,
+                                    self.singa_tensor, rhs)
+
     def __lt__(self, rhs):
         if isinstance(rhs, Tensor):
             return from_raw_tensor(
@@ -479,6 +487,13 @@ class Tensor(object):
         one /= self
         return one
 
+    def __rtruediv__(self, lhs):
+        lhs = float(lhs)
+        one = Tensor(self.shape, self.device, self.dtype)
+        one.set_value(lhs)
+        one /= self
+        return one
+
 ''' python functions for global functions in Tensor.h
 '''
 
@@ -938,7 +953,7 @@ def div(lhs, rhs, ret=None):
     '''
     if ret is None:
         # call Tensor.__div__()
-        return old_div(lhs, rhs)
+        return lhs / rhs
     else:
         if isinstance(rhs, Tensor):
             singa.Div(lhs.singa_tensor, rhs.singa_tensor, ret.singa_tensor)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/src/api/model_layer.i
----------------------------------------------------------------------
diff --git a/src/api/model_layer.i b/src/api/model_layer.i
index 92919fd..4760da3 100644
--- a/src/api/model_layer.i
+++ b/src/api/model_layer.i
@@ -29,6 +29,7 @@
 
 
 %{
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
 #include "singa/model/layer.h"
 #include "../src/model/layer/rnn.h"
 #include "../src/model/layer/cudnn_rnn.h"

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/src/api/model_optimizer.i
----------------------------------------------------------------------
diff --git a/src/api/model_optimizer.i b/src/api/model_optimizer.i
index 793df28..9b73d81 100644
--- a/src/api/model_optimizer.i
+++ b/src/api/model_optimizer.i
@@ -28,6 +28,7 @@
 %include "std_shared_ptr.i"
 
 %{
+#define SWIG_PYTHON_STRICT_BYTE_CHAR
 #include "singa/model/optimizer.h"
 #include "singa/proto/model.pb.h"
 using singa::Tensor;

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_layer.py
----------------------------------------------------------------------
diff --git a/test/python/test_layer.py b/test/python/test_layer.py
index c0f19f3..ec5becf 100644
--- a/test/python/test_layer.py
+++ b/test/python/test_layer.py
@@ -1,3 +1,4 @@
+from builtins import str
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_loss.py
----------------------------------------------------------------------
diff --git a/test/python/test_loss.py b/test/python/test_loss.py
index 78356f2..eb06b81 100644
--- a/test/python/test_loss.py
+++ b/test/python/test_loss.py
@@ -1,3 +1,5 @@
+from __future__ import division
+from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -45,7 +47,7 @@ class TestLoss(unittest.TestCase):
         sig.backward()
         l2 = sig.evaluate(True, self.x, self.y)
 
-        p = 1.0 / (1 + np.exp(-self.x_np))
+        p = old_div(1.0, (1 + np.exp(-self.x_np)))
         l = - (self.y_np * np.log(p) + (1-self.y_np) * np.log(1-p))
         self.assertAlmostEqual(l1.l1(), l2)
         self.assertAlmostEqual(l1.l1(), np.average(l))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_metric.py
----------------------------------------------------------------------
diff --git a/test/python/test_metric.py b/test/python/test_metric.py
index e7a51c3..8a22372 100644
--- a/test/python/test_metric.py
+++ b/test/python/test_metric.py
@@ -1,3 +1,5 @@
+from __future__ import division
+from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -50,7 +52,7 @@ class TestPrecision(unittest.TestCase):
 
     def test_evaluate(self):
         e = self.prcs.evaluate(self.x,self.y)
-        self.assertAlmostEqual(e, (0.5 + 1 + 0) / 3)
+        self.assertAlmostEqual(e, old_div((0.5 + 1 + 0), 3))
 
 class TestRecall(unittest.TestCase):
     def setUp(self):
@@ -72,13 +74,13 @@ class TestRecall(unittest.TestCase):
     def test_forward(self):
         r = self.recall.forward(self.x,self.y)
         self.assertAlmostEqual(tensor.to_numpy(r)[0], 0.5)
-        self.assertAlmostEqual(tensor.to_numpy(r)[1], 2.0 / 3)
+        self.assertAlmostEqual(tensor.to_numpy(r)[1], old_div(2.0, 3))
         self.assertAlmostEqual(tensor.to_numpy(r)[2], 0)
 
 
     def test_evaluate(self):
         e = self.recall.evaluate(self.x,self.y)
-        self.assertAlmostEqual(e, (0.5 + 2.0 / 3 + 0) / 3)
+        self.assertAlmostEqual(e, old_div((0.5 + old_div(2.0, 3) + 0), 3))
 
 if __name__ == '__main__':
     unittest.main()

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_net.py
----------------------------------------------------------------------
diff --git a/test/python/test_net.py b/test/python/test_net.py
index b19d868..afabc0d 100644
--- a/test/python/test_net.py
+++ b/test/python/test_net.py
@@ -1,3 +1,6 @@
+from __future__ import division
+from builtins import zip
+from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -41,7 +44,7 @@ class TestFeedForwardNet(unittest.TestCase):
         y.set_value(0)
         out, _ = ffn.evaluate(x, y)
         self.assertAlmostEqual(out * 3,
-                               - math.log(1.0/(1+math.exp(1))) -
+                               - math.log(old_div(1.0,(1+math.exp(1)))) -
                                math.log(0.5) - math.log(0.5),
                                5)
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_optimizer.py
----------------------------------------------------------------------
diff --git a/test/python/test_optimizer.py b/test/python/test_optimizer.py
index cfd13c0..11374f5 100644
--- a/test/python/test_optimizer.py
+++ b/test/python/test_optimizer.py
@@ -1,3 +1,7 @@
+from __future__ import division
+from builtins import zip
+from builtins import range
+from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -106,7 +110,7 @@ class TestOptimizer(unittest.TestCase):
         cons = opt.L2Constraint(threshold)
         cons.apply(0, self.W, self.g)
         g = tensor.to_numpy(self.g)
-        nrm = np.linalg.norm(self.np_g) / self.np_g.size
+        nrm = old_div(np.linalg.norm(self.np_g), self.np_g.size)
         for i in range(g.size):
             self.assertAlmostEqual(g[i], self.np_g[i] * threshold / nrm)
 
@@ -118,7 +122,7 @@ class TestOptimizer(unittest.TestCase):
         cons.apply(0, self.W, self.g)
         self.g.to_host()
         g = tensor.to_numpy(self.g)
-        nrm = np.linalg.norm(self.np_g) / self.np_g.size
+        nrm = old_div(np.linalg.norm(self.np_g), self.np_g.size)
         for i in range(g.size):
             self.assertAlmostEqual(g[i], self.np_g[i] * threshold / nrm)
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/test/python/test_tensor.py
----------------------------------------------------------------------
diff --git a/test/python/test_tensor.py b/test/python/test_tensor.py
index 9cd2411..3f86899 100644
--- a/test/python/test_tensor.py
+++ b/test/python/test_tensor.py
@@ -1,3 +1,5 @@
+from __future__ import division
+from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -150,7 +152,7 @@ class TestTensorMethods(unittest.TestCase):
     def test_rdiv(self):
         x = tensor.Tensor((3,))
         x.set_value(1)
-        y = 2 / x
+        y = old_div(2, x)
         self.assertEqual(tensor.average(y), 2.)
 
     def test_numpy_convert(self):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/tool/debian/postinst
----------------------------------------------------------------------
diff --git a/tool/debian/postinst b/tool/debian/postinst
index 2d63734..433ca49 100644
--- a/tool/debian/postinst
+++ b/tool/debian/postinst
@@ -16,6 +16,6 @@
 # limitations under the License.
 #
 
-pip install /usr/local/lib/singa/python
+pip3 install /usr/local/lib/singa/python
 rm -r /usr/local/lib/singa
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/c94b3dfd/tool/opencl/clsrc_to_str.py
----------------------------------------------------------------------
diff --git a/tool/opencl/clsrc_to_str.py b/tool/opencl/clsrc_to_str.py
index 24400f7..8ca94a0 100755
--- a/tool/opencl/clsrc_to_str.py
+++ b/tool/opencl/clsrc_to_str.py
@@ -57,7 +57,7 @@ if __name__ == "__main__":
         fout.write(license)
         fout.write("#include <string>\n\n")
         fout.write("namespace singa {\n namespace opencl {\n")
-        for name, path in files.items():
+        for name, path in list(files.items()):
             with open(path, 'r') as fin:
                 src = fin.read()
                 src = repr(src)


[03/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/14f0d8cd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/14f0d8cd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/14f0d8cd

Branch: refs/heads/master
Commit: 14f0d8cdf6b85928681e434fb1984615b773c3c0
Parents: e5c438c
Author: Moaz Reyad <mo...@gmail.com>
Authored: Sat May 27 14:32:31 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:15:59 2017 +0800

----------------------------------------------------------------------
 CMakeLists.txt               | 38 +++++++++++++++++++++++++++-----------
 cmake/Dependencies.cmake     | 11 ++++++++---
 python/setup.py.in           |  6 ++++--
 python/singa/command.py      | 24 ++++++++++++++----------
 python/singa/converter.py    | 12 ++++++++----
 python/singa/data.py         | 14 +++++++++-----
 python/singa/device.py       |  1 +
 python/singa/image_tool.py   | 24 ++++++++++++++----------
 python/singa/initializer.py  |  8 +++++---
 python/singa/layer.py        |  9 +++++++--
 python/singa/loss.py         |  8 ++++++--
 python/singa/metric.py       | 11 ++++++++---
 python/singa/net.py          | 27 +++++++++++++++++----------
 python/singa/optimizer.py    |  8 ++++++--
 python/singa/snapshot.py     |  5 ++++-
 python/singa/tensor.py       | 15 ++++++++++-----
 tool/debian-python2/postinst | 21 +++++++++++++++++++++
 17 files changed, 169 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f71ce69..0522f61 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -122,13 +122,13 @@ IF (USE_MODULES)
     #ENDIF()
     ExternalProject_Add(protobuf
         DOWNLOAD_COMMAND "wget"
-        "http://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz"
-        "-O" "protobuf-2.6.1.tar.gz"
+        "https://github.com/google/protobuf/archive/v3.3.0.tar.gz"
+        "-O" "protobuf-3.3.0.tar.gz"
         UPDATE_COMMAND "tar" "zxvf"
-        "${CMAKE_BINARY_DIR}/protobuf-prefix/src/protobuf-2.6.1.tar.gz" "-C" ".."
-        SOURCE_DIR "protobuf-2.6.1/"
+        "${CMAKE_BINARY_DIR}/protobuf-prefix/src/protobuf-3.3.0.tar.gz" "-C" ".."
+        SOURCE_DIR "protobuf-3.3.0/"
         BUILD_IN_SOURCE 1
-        CONFIGURE_COMMAND "./configure" "--disable-shared"
+        CONFIGURE_COMMAND "./autogen.sh" COMMAND "./configure" "--disable-shared"
         "--prefix=${CMAKE_BINARY_DIR}/" "CXXFLAGS=-fPIC"
         INSTALL_COMMAND "make" "install"
         )
@@ -192,7 +192,11 @@ IF(PACKAGE)
 		SET(CORE_DEPENDENCIES "libgoogle-glog-dev, libprotobuf-dev, libopenblas-dev, libstdc++6, libc6")
 	ENDIF()
 
-	SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python-dev, libpython2.7, python-pip, python-numpy, python-pillow")
+	IF(PYTHON2)
+		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python-dev, libpython2.7, python-pip, python-numpy, python-pillow")
+	ELSE()
+		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python3, python3-dev, python3-pip, python3-numpy, python3-pillow")
+	ENDIF()
 
 	SET(CPACK_GENERATOR "DEB")
 	SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Apache Incubator <de...@singa.incubator.apache.org>")
@@ -206,12 +210,24 @@ IF(PACKAGE)
 		SET(CPACK_DEBIAN_PACKAGE_DEPENDS ${PYTHON_DEPENDENCIES})
 		SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian/postinst" )
 		SET(CPACK_DEBIAN_PACKAGE_PREDEPENDS "ca-certificates")
-		IF (USE_CUDA)
-			SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa-cuda")
-			SET(CPACK_PACKAGE_FILE_NAME "python-singa-cuda-${PACKAGE_VERSION}")
+		IF(PYTHON2)
+			SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian-python2/postinst" )
+			IF (USE_CUDA)
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa-cuda")
+				SET(CPACK_PACKAGE_FILE_NAME "python-singa-cuda-${PACKAGE_VERSION}")
+			ELSE()
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa")
+				SET(CPACK_PACKAGE_FILE_NAME "python-singa-${PACKAGE_VERSION}")
+			ENDIF()
 		ELSE()
-			SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa")
-			SET(CPACK_PACKAGE_FILE_NAME "python-singa-${PACKAGE_VERSION}")
+			SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian/postinst" )
+			IF (USE_CUDA)
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python3-singa-cuda")
+				SET(CPACK_PACKAGE_FILE_NAME "python3-singa-cuda-${PACKAGE_VERSION}")
+			ELSE()
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python3-singa")
+				SET(CPACK_PACKAGE_FILE_NAME "python3-singa-${PACKAGE_VERSION}")
+			ENDIF()
 		ENDIF()
 	ELSE()
 		SET(CPACK_DEBIAN_PACKAGE_NAME "singa")

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/cmake/Dependencies.cmake
----------------------------------------------------------------------
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
index 83c5187..aa3c090 100644
--- a/cmake/Dependencies.cmake
+++ b/cmake/Dependencies.cmake
@@ -51,7 +51,7 @@ IF(USE_MODULES)
     #ENDIF()
     #ENDIF()
 ELSE()
-    FIND_PACKAGE( Protobuf REQUIRED )
+    FIND_PACKAGE( Protobuf 3.0 REQUIRED )
     #MESSAGE(STATUS "proto libs " ${PROTOBUF_LIBRARY})
     LIST(APPEND SINGA_LINKER_LIBS ${PROTOBUF_LIBRARY})
     #IF(USE_CBLAS)
@@ -124,8 +124,13 @@ ENDIF()
 #MESSAGE(STATUS "link lib : " ${SINGA_LINKER_LIBS})
 
 IF(USE_PYTHON)
-    FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
-    FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
+    IF(PYTHON2)
+        FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
+        FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
+    ELSE()
+        FIND_PACKAGE(PythonLibs 3.0 REQUIRED)
+        FIND_PACKAGE(PythonInterp 3.0 REQUIRED)
+    ENDIF()
     FIND_PACKAGE(SWIG 3.0 REQUIRED)
 ENDIF()
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/setup.py.in
----------------------------------------------------------------------
diff --git a/python/setup.py.in b/python/setup.py.in
index 6b3e5b5..044710f 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -50,6 +50,7 @@ setup(
         'Programming Language :: Python :: 2',
         'Programming Language :: Python :: 2.6',
         'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3',
         ],
 
     keywords='deep learning singa apache',
@@ -60,11 +61,12 @@ setup(
 
     install_requires=[
         'numpy>=1.11.0',
-        'protobuf>=2.5.0',
+        'protobuf>=3',
         'unittest-xml-reporting',
         'flask>=0.10.1',
         'flask_cors>=3.0.2',
-        'pillow>=2.3.0'
+        'pillow>=2.3.0',
+        'future'
         ],
 
     #List additional groups of dependencies here (e.g. development

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/command.py
----------------------------------------------------------------------
diff --git a/python/singa/command.py b/python/singa/command.py
index f14c8c5..90c51cc 100644
--- a/python/singa/command.py
+++ b/python/singa/command.py
@@ -21,12 +21,16 @@ This script is the main entrance for user to run singa inside a model workspace
 
 To use this script, user sudo install these dependencies: flask pillow and protobuf
 '''
+from __future__ import print_function
 
+from future import standard_library
+standard_library.install_aliases()
+from builtins import str
 import sys, glob, os, random, shutil, time
 from flask import Flask, request, redirect, url_for
 import numpy as np
-import ConfigParser
-import urllib, traceback
+import configparser
+import urllib.request, urllib.parse, urllib.error, traceback
 
 
 from argparse import ArgumentParser
@@ -42,7 +46,7 @@ welcome to singa
 '''
 
 app = Flask(__name__)
-config = ConfigParser.RawConfigParser()
+config = configparser.RawConfigParser()
 service = {}
 data_path = "data_"
 parameter_path = "parameter_"
@@ -123,19 +127,19 @@ USAGE
         parameter_file=get_parameter(parameter_file)
 
         if parameter_file:
-            print "load parameter file: %s" % parameter_file
+            print("load parameter file: %s" % parameter_file)
             model.load(parameter_file)
 
         if use_cpu:
             raise CLIError("Currently cpu is not support!")
         else:
-            print "runing with gpu"
+            print("runing with gpu")
             d = device.create_cuda_gpu()
 
         model.to_device(d)
 
         if mode == "serve":
-            print "runing singa in serve mode, listen to  port: %s " % port
+            print("runing singa in serve mode, listen to  port: %s " % port)
             global service
             from serve import Service
             service =Service(model,d)
@@ -143,7 +147,7 @@ USAGE
             app.debug = debug
             app.run(host='0.0.0.0', port= port)
         elif mode == "train":
-            print "runing singa in train mode"
+            print("runing singa in train mode")
             global trainer
             from train import Trainer
             trainer= Trainer(model,d)
@@ -156,7 +160,7 @@ USAGE
     except KeyboardInterrupt:
         ### handle keyboard interrupt ###
         return 0
-    except Exception, e:
+    except Exception as e:
         if debug:
             traceback.print_exc()
             raise(e)
@@ -172,7 +176,7 @@ def file_prepare(reload_data=False):
     if not reload_data and os.path.exists("data_.py"):
         return
 
-    print "download file"
+    print("download file")
     #clean data
     shutil.rmtree("data_.py",ignore_errors=True)
     shutil.rmtree("data_",ignore_errors=True)
@@ -203,7 +207,7 @@ def download_file(name,path,dest):
     if (path.startswith('http')):
         file_name = path.split('/')[-1]
         target = os.path.join(dest,file_name)
-        urllib.urlretrieve(path,target)
+        urllib.request.urlretrieve(path,target)
     return name,target
 
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/converter.py
----------------------------------------------------------------------
diff --git a/python/singa/converter.py b/python/singa/converter.py
index cc42ef0..dc195f2 100644
--- a/python/singa/converter.py
+++ b/python/singa/converter.py
@@ -15,6 +15,10 @@
 # limitations under the License.
 # =============================================================================
 
+from __future__ import print_function
+from builtins import str
+from builtins import range
+from builtins import object
 from google.protobuf import text_format
 from singa import layer
 from singa import metric
@@ -25,7 +29,7 @@ from .proto import caffe_pb2
 import numpy as np
 
 
-class CaffeConverter:
+class CaffeConverter(object):
 
     def __init__(self, net_proto, solver_proto = None, input_sample_shape =
             None, param_path = None):
@@ -158,9 +162,9 @@ class CaffeConverter:
                     layer.engine = self.convert_engine(layer_confs[i], 0)
                 lyr = layer.Layer(conf.name, conf)
                 if len(net.layers) == 0:
-                    print 'input sample shape: ', self.input_sample_shape
+                    print('input sample shape: ', self.input_sample_shape)
                     lyr.setup(self.input_sample_shape)
-                    print lyr.name, lyr.get_output_sample_shape()
+                    print(lyr.name, lyr.get_output_sample_shape())
                 if layer_confs[i].type == 'InnerProduct' or layer_confs[i].type == 14:
                     net.add(layer.Flatten('flat' + str(flatten_id)))
                     flatten_id += 1
@@ -226,4 +230,4 @@ class CaffeConverter:
                 i += 1
                 params[i].copy_from_numpy(bias)
                 i += 1
-                print 'converting layer {0}, wmat shape = {1}, bias shape = {2}'.format(layer.name, w.shape, bias.shape)
+                print('converting layer {0}, wmat shape = {1}, bias shape = {2}'.format(layer.name, w.shape, bias.shape))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/data.py
----------------------------------------------------------------------
diff --git a/python/singa/data.py b/python/singa/data.py
index 492d218..753edbf 100644
--- a/python/singa/data.py
+++ b/python/singa/data.py
@@ -48,7 +48,11 @@ Example usage::
         img.save('img%d.png' % idx)
     data.end()
 '''
+from __future__ import print_function
+from __future__ import absolute_import
 
+from builtins import range
+from builtins import object
 import os
 import random
 import time
@@ -56,7 +60,7 @@ from multiprocessing import Process, Queue
 import numpy as np
 
 
-class ImageBatchIter:
+class ImageBatchIter(object):
     '''Utility for iterating over an image dataset to get mini-batches.
 
     Args:
@@ -97,7 +101,7 @@ class ImageBatchIter:
         self.p.start()
         return
 
-    def next(self):
+    def __next__(self):
         assert self.p is not None, 'call start before next'
         while self.queue.empty():
             time.sleep(0.1)
@@ -164,7 +168,7 @@ class ImageBatchIter:
 
 
 if __name__ == '__main__':
-    import image_tool
+    from . import image_tool
     from PIL import Image
     tool = image_tool.ImageTool()
 
@@ -179,8 +183,8 @@ if __name__ == '__main__':
                           image_folder='images/',
                           capacity=10)
     data.start()
-    imgs, labels = data.next()
-    print labels
+    imgs, labels = next(data)
+    print(labels)
     for idx in range(imgs.shape[0]):
         img = Image.fromarray(imgs[idx].astype(np.uint8).transpose(1, 2, 0),
                               'RGB')

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/device.py
----------------------------------------------------------------------
diff --git a/python/singa/device.py b/python/singa/device.py
index fdd2a92..a1625e2 100644
--- a/python/singa/device.py
+++ b/python/singa/device.py
@@ -22,6 +22,7 @@ to call singa::Device and its methods.
 TODO(wangwei) implement py CudaGPU class.
 '''
 
+from builtins import object
 from . import singa_wrap as singa
 
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/image_tool.py
----------------------------------------------------------------------
diff --git a/python/singa/image_tool.py b/python/singa/image_tool.py
index ed865f1..529f73b 100644
--- a/python/singa/image_tool.py
+++ b/python/singa/image_tool.py
@@ -28,7 +28,11 @@ Example usage::
         img.save('%d.png' % idx)
 
 '''
+from __future__ import division
 
+from builtins import range
+from builtins import object
+from past.utils import old_div
 import random
 import numpy as np
 from PIL import Image, ImageEnhance
@@ -69,7 +73,7 @@ def crop(img, patch, position):
     elif position == 'right_bottom':
         left, upper = img.size[0]-patch[0], img.size[1]-patch[1]
     elif position == 'center':
-        left, upper = (img.size[0]-patch[0])/2, (img.size[1]-patch[1])/2
+        left, upper = old_div((img.size[0]-patch[0]),2), old_div((img.size[1]-patch[1]),2)
     else:
         raise Exception('position is wrong')
 
@@ -92,8 +96,8 @@ def crop_and_resize(img, patch, position):
         left, upper = 0, 0
         right, bottom = size[1], size[1]
     elif position == 'center':
-        left, upper = (size[0]-size[1])/2, 0
-        right, bottom = (size[0]+size[1])/2, size[1]
+        left, upper = old_div((size[0]-size[1]),2), 0
+        right, bottom = old_div((size[0]+size[1]),2), size[1]
     elif position == 'right':
         left, upper = size[0]-size[1], 0
         right, bottom = size[0], size[1]
@@ -101,8 +105,8 @@ def crop_and_resize(img, patch, position):
         left, upper = 0, 0
         right, bottom = size[0], size[0]
     elif position == 'middle':
-        left, upper = 0, (size[1]-size[0])/2
-        right, bottom = size[0], (size[1]+size[0])/2
+        left, upper = 0, old_div((size[1]-size[0]),2)
+        right, bottom = size[0], old_div((size[1]+size[0]),2)
     elif position == 'bottom':
         left, upper = 0, size[1]-size[0]
         right, bottom = size[0], size[1]
@@ -192,10 +196,10 @@ def flip_down(img):
 
 
 def get_list_sample(l, sample_size):
-    return [l[i] for i in sorted(random.sample(xrange(len(l)), sample_size))]
+    return [l[i] for i in sorted(random.sample(range(len(l)), sample_size))]
 
 
-class ImageTool():
+class ImageTool(object):
     '''A tool for image augmentation.
 
     For operations with inplace=True, the returned value is the ImageTool
@@ -238,7 +242,7 @@ class ImageTool():
             rng: a tuple (begin,end), include begin, exclude end
             inplace: inplace imgs or not ( return new_imgs)
         '''
-        size_list = range(rng[0], rng[1])
+        size_list = list(range(rng[0], rng[1]))
         return self.resize_by_list(size_list, 1, inplace)
 
     def resize_by_list(self, size_list, num_case=1, inplace=True):
@@ -273,7 +277,7 @@ class ImageTool():
             rng: a tuple (begin,end) in degree, include begin, exclude end
             inplace: inplace imgs or not ( return new_imgs)
         '''
-        angle_list = range(rng[0], rng[1])
+        angle_list = list(range(rng[0], rng[1]))
         return self.rotate_by_list(angle_list, 1, inplace)
 
     def rotate_by_list(self, angle_list, num_case=1, inplace=True):
@@ -391,7 +395,7 @@ class ImageTool():
         if num_case == patch5 + patch3:
             count = patch5
         else:
-            sample_list = range(0, patch5 + patch3)
+            sample_list = list(range(0, patch5 + patch3))
             samples = get_list_sample(sample_list, num_case)
             count = 0
             for s in samples:

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/initializer.py
----------------------------------------------------------------------
diff --git a/python/singa/initializer.py b/python/singa/initializer.py
index fb99663..5d5f31e 100644
--- a/python/singa/initializer.py
+++ b/python/singa/initializer.py
@@ -26,7 +26,9 @@ Example usages::
     initializer.uniform(x, 3, 5) # use both fan_in and fan_out
     initializer.uniform(x, 3, 0)  # use only fan_in
 '''
+from __future__ import division
 
+from past.utils import old_div
 import math
 
 
@@ -89,7 +91,7 @@ def xavier(t):
         t (Tensor): the parater tensor
     '''
 
-    scale = math.sqrt(6.0 / (t.shape[0] + t.shape[1]))
+    scale = math.sqrt(old_div(6.0, (t.shape[0] + t.shape[1])))
     t.uniform(-scale, scale)
 
 
@@ -102,7 +104,7 @@ def glorot(t):
     Args:
         t (Tensor): the parater tensor
     '''
-    scale = math.sqrt(2.0 / (t.shape[0] + t.shape[1]))
+    scale = math.sqrt(old_div(2.0, (t.shape[0] + t.shape[1])))
     t.gaussian(0, 1)
     t *= scale
 
@@ -119,4 +121,4 @@ def msra(t):
     Args:
         t (Tensor): the parater tensor
     '''
-    t.gaussian(0, math.sqrt(2.0 / t.shape[0]))
+    t.gaussian(0, math.sqrt(old_div(2.0, t.shape[0])))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/layer.py
----------------------------------------------------------------------
diff --git a/python/singa/layer.py b/python/singa/layer.py
index 026a766..2cdfe69 100644
--- a/python/singa/layer.py
+++ b/python/singa/layer.py
@@ -44,11 +44,16 @@ Example usages::
     # dp is a list of tensors for parameter gradients
     dx, dp = conv.backward(kTrain, dy)
 """
+from __future__ import division
+from __future__ import absolute_import
 
+from builtins import str
+from builtins import range
+from builtins import object
 from sets import Set
 from . import singa_wrap
 from .proto import model_pb2
-import tensor
+from . import tensor
 
 
 engine = 'cudnn'
@@ -1217,7 +1222,7 @@ def _set_kernel_stride_pad(conf, kernel, stride, border_mode, pad, in_shape):
                      0)
             assert ph % 2 == 0 and pw % 2 == 0, 'ph=%d and pw=%d are not even' \
                 % (ph, pw)
-            pad = (ph / 2, pw / 2)
+            pad = (ph // 2, pw // 2)
         elif mode == 'valid':
             pad = (0, 0)
         else:

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/loss.py
----------------------------------------------------------------------
diff --git a/python/singa/loss.py b/python/singa/loss.py
index 7fd3d77..d643218 100644
--- a/python/singa/loss.py
+++ b/python/singa/loss.py
@@ -34,11 +34,15 @@ Example usage::
     l = f.forward(True, x, y)  # l is tensor with 3 loss values
     g = f.backward()  # g is a tensor containing all gradients of x w.r.t l
 '''
+from __future__ import division
+from __future__ import absolute_import
 
 
+from past.utils import old_div
+from builtins import object
 from . import singa_wrap as singa
 from proto import model_pb2
-import tensor
+from . import tensor
 import numpy as np
 
 
@@ -210,4 +214,4 @@ class SquaredError(Loss):
         Returns:
             a float value as the averaged error
         '''
-        return tensor.sum(tensor.square(x - y) * 0.5) / x.size()
+        return old_div(tensor.sum(tensor.square(x - y) * 0.5), x.size())

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/metric.py
----------------------------------------------------------------------
diff --git a/python/singa/metric.py b/python/singa/metric.py
index 64a1b72..8495c0c 100644
--- a/python/singa/metric.py
+++ b/python/singa/metric.py
@@ -34,10 +34,15 @@ Example usage::
     acc = f.evaluate(x, y)  # averaged accuracy over all 3 samples in x
 
 '''
+from __future__ import division
+from __future__ import absolute_import
 
 
+from builtins import range
+from past.utils import old_div
+from builtins import object
 from . import singa_wrap as singa
-import tensor
+from . import tensor
 import numpy as np
 
 
@@ -129,7 +134,7 @@ class Precision(Metric):
 
             #Num of common labels among prediction and groundtruth
             num_intersect = np.intersect1d(pred_np[i], label_np).size
-            prcs_np[i] = num_intersect / float(self.top_k)
+            prcs_np[i] = old_div(num_intersect, float(self.top_k))
 
         precision = tensor.from_numpy(prcs_np)
 
@@ -192,7 +197,7 @@ class Recall(Metric):
 
             #Num of common labels among prediction and groundtruth
             num_intersect = np.intersect1d(pred_np[i], label_np).size
-            recall_np[i] = float(num_intersect) / label_np.size
+            recall_np[i] = old_div(float(num_intersect), label_np.size)
 
         recall = tensor.from_numpy(recall_np)
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/net.py
----------------------------------------------------------------------
diff --git a/python/singa/net.py b/python/singa/net.py
index faaef2b..c49b9fa 100644
--- a/python/singa/net.py
+++ b/python/singa/net.py
@@ -53,13 +53,20 @@ Example usages::
     y = net.predict(x)
     print tensor.to_numpy(y)
 """
-
+from __future__ import print_function
+from __future__ import absolute_import
+
+from future import standard_library
+standard_library.install_aliases()
+from builtins import zip
+from builtins import str
+from builtins import object
 from .proto.model_pb2 import kTrain, kEval
-from __init__ import __version__
-import tensor
-import layer
-import snapshot
-import cPickle as pickle
+from .__init__ import __version__
+from . import tensor
+from . import layer
+from . import snapshot
+import pickle as pickle
 
 import os
 
@@ -137,7 +144,7 @@ class FeedForwardNet(object):
         else:
             self.out_sample_shape_of_layer[lyr.name] = [out_shape]
         self.layers.append(lyr)
-        print(lyr.name, out_shape)
+        print((lyr.name, out_shape))
         return lyr
 
     def param_values(self):
@@ -334,7 +341,7 @@ class FeedForwardNet(object):
         # print output_of_layer
         ret.update(output_of_layer)
         if len(ret) == 1:
-            return ret.values()[0]
+            return list(ret.values())[0]
         else:
             return ret
 
@@ -494,6 +501,6 @@ class FeedForwardNet(object):
                     val.copy_from_numpy(params[name])
             except AssertionError as err:
                 print('Error from copying values for param: %s' % name)
-                print('shape of param vs checkpoint',
-                      val.shape, params[name].shape)
+                print(('shape of param vs checkpoint',
+                      val.shape, params[name].shape))
                 raise err

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/optimizer.py
----------------------------------------------------------------------
diff --git a/python/singa/optimizer.py b/python/singa/optimizer.py
index 614fe6d..8f1fe8e 100644
--- a/python/singa/optimizer.py
+++ b/python/singa/optimizer.py
@@ -31,10 +31,14 @@ Example usage::
   sgd.apply(1, g, p, 'param')  # use the global lr=0.1 for epoch 1
   sgd.apply_with_lr(2, 0.03, g, p, 'param')  # use lr=0.03 for epoch 2
 '''
+from __future__ import division
+from __future__ import absolute_import
 
+from past.utils import old_div
+from builtins import object
 import math
 from . import singa_wrap as singa
-import tensor
+from . import tensor
 from proto import model_pb2
 
 
@@ -434,5 +438,5 @@ class L2Constraint(Constraint):
 
     def apply(self, epoch, value, grad, step=-1):
         nrm = grad.l2()
-        grad *= self.threshold / nrm
+        grad *= old_div(self.threshold, nrm)
         return grad

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/snapshot.py
----------------------------------------------------------------------
diff --git a/python/singa/snapshot.py b/python/singa/snapshot.py
index 3e1298f..4c359fc 100644
--- a/python/singa/snapshot.py
+++ b/python/singa/snapshot.py
@@ -29,9 +29,12 @@ Example usages::
     for k, v in params.iteritems():
         sn2.write(k, v)
 '''
+from __future__ import absolute_import
 
+from builtins import str
+from builtins import object
 from . import singa_wrap as singa
-import tensor
+from . import tensor
 
 
 class Snapshot(object):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/python/singa/tensor.py
----------------------------------------------------------------------
diff --git a/python/singa/tensor.py b/python/singa/tensor.py
index d36abdc..fabd84a 100644
--- a/python/singa/tensor.py
+++ b/python/singa/tensor.py
@@ -53,12 +53,17 @@ Tensor module functions
 
 Every Tesor instance must be initialized before reading data from it.
 """
+from __future__ import division
+from __future__ import print_function
+from __future__ import absolute_import
 
+from past.utils import old_div
+from builtins import object
 import numpy as np
 from functools import reduce
 from .proto import core_pb2
 from . import singa_wrap as singa
-import device as pydevice
+from . import device as pydevice
 
 int32 = core_pb2.kInt
 float32 = core_pb2.kFloat32
@@ -214,7 +219,7 @@ class Tensor(object):
         elif dt == np.int or dt == np.int32:
             self.singa_tensor.CopyIntDataFromHostPtr(np_array)
         else:
-            print 'Not implemented yet for ', dt
+            print('Not implemented yet for ', dt)
 
     def copy_data(self, t):
         '''Copy data from other Tensor instance.
@@ -584,7 +589,7 @@ def to_numpy(t):
     elif th.dtype == core_pb2.kInt:
         np_array = th.singa_tensor.GetIntValue(int(th.size()))
     else:
-        print 'Not implemented yet for ', th.dtype
+        print('Not implemented yet for ', th.dtype)
     return np_array.reshape(th.shape)
 
 
@@ -746,7 +751,7 @@ def average(t, axis=None):
     if t.ndim() > 1:
         return _call_singa_func(singa.Average, t.singa_tensor, axis)
     else:
-        return singa.SumAsFloat(t.singa_tensor) / t.size()
+        return old_div(singa.SumAsFloat(t.singa_tensor), t.size())
 
 
 def softmax(t, out=None):
@@ -933,7 +938,7 @@ def div(lhs, rhs, ret=None):
     '''
     if ret is None:
         # call Tensor.__div__()
-        return lhs / rhs
+        return old_div(lhs, rhs)
     else:
         if isinstance(rhs, Tensor):
             singa.Div(lhs.singa_tensor, rhs.singa_tensor, ret.singa_tensor)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/14f0d8cd/tool/debian-python2/postinst
----------------------------------------------------------------------
diff --git a/tool/debian-python2/postinst b/tool/debian-python2/postinst
new file mode 100644
index 0000000..2d63734
--- /dev/null
+++ b/tool/debian-python2/postinst
@@ -0,0 +1,21 @@
+#!/bin/bash
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+pip install /usr/local/lib/singa/python
+rm -r /usr/local/lib/singa
+


[15/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3

use python2 as default; -DPYTHON3=ON for py3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/0f86cd5a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/0f86cd5a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/0f86cd5a

Branch: refs/heads/master
Commit: 0f86cd5a34968ab3cf46aee11291fed9dcad38fd
Parents: 57dbe42
Author: wangwei <wa...@comp.nus.edu.sg>
Authored: Wed Aug 2 14:37:20 2017 +0000
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Fri Aug 4 16:32:04 2017 +0800

----------------------------------------------------------------------
 CMakeLists.txt           | 26 +++++++++++++-------------
 cmake/Dependencies.cmake | 10 +++++-----
 tool/conda/build.sh      |  4 +++-
 tool/conda/meta.yaml     | 25 ++++++++++---------------
 4 files changed, 31 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/0f86cd5a/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index fbd4f9c..2a8210a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -192,10 +192,10 @@ IF(PACKAGE)
 		SET(CORE_DEPENDENCIES "libgoogle-glog-dev, libprotobuf-dev, libopenblas-dev, libstdc++6, libc6")
 	ENDIF()
 
-	IF(PYTHON2)
-		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python-dev, libpython2.7, python-pip, python-numpy, python-pillow")
-	ELSE()
+	IF(PYTHON3)
 		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python3, python3-dev, python3-pip, python3-numpy, python3-pillow, python3-matplotlib")
+	ELSE()
+		SET(PYTHON_DEPENDENCIES "${CORE_DEPENDENCIES}, python-dev, libpython2.7, python-pip, python-numpy, python-pillow")
 	ENDIF()
 
 	SET(CPACK_GENERATOR "DEB")
@@ -210,16 +210,7 @@ IF(PACKAGE)
 		SET(CPACK_DEBIAN_PACKAGE_DEPENDS ${PYTHON_DEPENDENCIES})
 		SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian/postinst" )
 		SET(CPACK_DEBIAN_PACKAGE_PREDEPENDS "ca-certificates")
-		IF(PYTHON2)
-			SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian-python2/postinst" )
-			IF (USE_CUDA)
-				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa-cuda")
-				SET(CPACK_PACKAGE_FILE_NAME "python-singa-cuda-${PACKAGE_VERSION}")
-			ELSE()
-				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa")
-				SET(CPACK_PACKAGE_FILE_NAME "python-singa-${PACKAGE_VERSION}")
-			ENDIF()
-		ELSE()
+		IF(PYTHON3)
 			SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian/postinst" )
 			IF (USE_CUDA)
 				SET(CPACK_DEBIAN_PACKAGE_NAME "python3-singa-cuda")
@@ -228,6 +219,15 @@ IF(PACKAGE)
 				SET(CPACK_DEBIAN_PACKAGE_NAME "python3-singa")
 				SET(CPACK_PACKAGE_FILE_NAME "python3-singa-${PACKAGE_VERSION}")
 			ENDIF()
+		ELSE()
+			SET(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${PROJECT_SOURCE_DIR}/tool/debian-python2/postinst" )
+			IF (USE_CUDA)
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa-cuda")
+				SET(CPACK_PACKAGE_FILE_NAME "python-singa-cuda-${PACKAGE_VERSION}")
+			ELSE()
+				SET(CPACK_DEBIAN_PACKAGE_NAME "python-singa")
+				SET(CPACK_PACKAGE_FILE_NAME "python-singa-${PACKAGE_VERSION}")
+			ENDIF()
 		ENDIF()
 	ELSE()
 		SET(CPACK_DEBIAN_PACKAGE_NAME "singa")

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/0f86cd5a/cmake/Dependencies.cmake
----------------------------------------------------------------------
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
index 07736a0..956c121 100644
--- a/cmake/Dependencies.cmake
+++ b/cmake/Dependencies.cmake
@@ -124,15 +124,15 @@ ENDIF()
 #MESSAGE(STATUS "link lib : " ${SINGA_LINKER_LIBS})
 
 IF(USE_PYTHON)
-    IF(PYTHON2)
-        FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
-        FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
-	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
-    ELSE()
+    IF(PYTHON3)
         set(Python_ADDITIONAL_VERSIONS 3.6)
         FIND_PACKAGE(PythonLibs 3 REQUIRED)
         FIND_PACKAGE(PythonInterp 3 REQUIRED)
 	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
+    ELSE()
+        FIND_PACKAGE(PythonLibs 2.7 REQUIRED)
+        FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
+	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
     ENDIF()
 ENDIF()
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/0f86cd5a/tool/conda/build.sh
----------------------------------------------------------------------
diff --git a/tool/conda/build.sh b/tool/conda/build.sh
index 7bd9023..6b3f262 100644
--- a/tool/conda/build.sh
+++ b/tool/conda/build.sh
@@ -28,6 +28,8 @@ cd build
 USE_CUDA=ON
 # singa with cuda and cudnn has the name as : singa-cudaxx-cudnnxx
 if  [ "$PKG_NAME" == "singa" ]; then USE_CUDA=OFF; fi
-cmake -DCMAKE_INSTALL_PREFIX=$PREFIX -DUSE_CUDA=$USE_CUDA ..
+PYTHON3=OFF
+if  [ "$PY3K" == "True" ]; then PYTHON3=ON; fi
+cmake -DCMAKE_INSTALL_PREFIX=$PREFIX -DUSE_CUDA=$USE_CUDA -DPYTHON3=$PYTHON3 ..
 make
 make install

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/0f86cd5a/tool/conda/meta.yaml
----------------------------------------------------------------------
diff --git a/tool/conda/meta.yaml b/tool/conda/meta.yaml
index bb65ce4..1c2004d 100644
--- a/tool/conda/meta.yaml
+++ b/tool/conda/meta.yaml
@@ -3,8 +3,7 @@ package:
   version: "{{ GIT_DESCRIBE_TAG }}"
 
 source:
-  path: ../../
-
+  git_url: https://github.com/apache/incubator-singa.git
 
 build:
   number: {{ GIT_DESCRIBE_NUMBER }}
@@ -15,32 +14,28 @@ build:
 
 requirements:
   build:
-    - python 2.7* [py27]
-    - python 3.6* [py36]
-    - numpy >=1.10
-    - swig >=3.0
-    - openblas >=0.2.10
-    - protobuf 3.2
+    - swig 3.0.2
+    - openblas 0.2.19
+    - protobuf 3.2.0
     - glog 0.3.4
     - libgfortran 3.0.0 # [osx]
     - gcc 4.8.5 # [linux]
-    - python 2.7*
+    - python 2.7* [py27]
+    - python 3.6* [py36]
     - numpy 1.12.0
 
   run:
-    - python 2.7* [py27]
-    - python 3.6* [py36]
-    - numpy >=1.10
-    - protobuf 3.2
+    - openblas 0.2.19
+    - protobuf 3.2.0
     - glog 0.3.4
     - libgfortran 3.0.0 # [osx]
     - libgcc 4.8.5 # [linux]
-    - python 2.7*
+    - python 2.7* [py27]
+    - python 3.6* [py36]
     - numpy >=1.12.0
     - flask >=0.10.1
     - flask-cors >=3.0.2
     - pillow >=2.3.0
-    - libgcc 4.8.5 # [linux]
 
 test:
   source_files:


[04/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3

Replace old_div with the corresponding / or //
Remove 'from future.standard_library import install_aliases' when not necessary
TODO test on both py2 and py3 env


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/01b7a74b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/01b7a74b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/01b7a74b

Branch: refs/heads/master
Commit: 01b7a74bafb782fb37bd86cafe5ab9e6000f442d
Parents: ff1806b
Author: Wei Wang <wa...@comp.nus.edu.sg>
Authored: Fri Jul 14 21:58:20 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:16:00 2017 +0800

----------------------------------------------------------------------
 examples/caffe/predict.py         |  20 +--
 examples/char-rnn/sample.py       |  21 ++-
 examples/char-rnn/train.py        |  43 +++---
 examples/cifar10/predict.py       |   9 +-
 examples/cifar10/resnet.py        |   8 --
 examples/cifar10/train.py         |  25 ++--
 examples/imagenet/resnet/serve.py |  43 +++---
 examples/mnist/train.py           |  41 +++---
 python/rafiki/agent.py            |  48 +++----
 python/setup.py.in                |   7 +-
 python/singa/command.py           | 244 ---------------------------------
 python/singa/image_tool.py        |  11 +-
 python/singa/initializer.py       |   8 +-
 python/singa/layer.py             |   1 +
 python/singa/loss.py              |  11 +-
 python/singa/metric.py            |  28 ++--
 python/singa/net.py               |  11 +-
 python/singa/optimizer.py         |  17 ++-
 python/singa/tensor.py            |   5 +-
 test/python/test_loss.py          |   6 +-
 test/python/test_metric.py        |  32 ++---
 test/python/test_net.py           |   7 +-
 test/python/test_optimizer.py     |  14 +-
 test/python/test_tensor.py        |   5 +-
 tool/opencl/clsrc_to_str.py       |  10 +-
 25 files changed, 203 insertions(+), 472 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/caffe/predict.py
----------------------------------------------------------------------
diff --git a/examples/caffe/predict.py b/examples/caffe/predict.py
index 62e6a86..0a93b1c 100644
--- a/examples/caffe/predict.py
+++ b/examples/caffe/predict.py
@@ -1,6 +1,3 @@
-from __future__ import print_function
-from builtins import input
-from builtins import range
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,6 +14,10 @@ from builtins import range
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # =============================================================================
+from __future__ import print_function
+from builtins import input
+from builtins import range
+
 import numpy as np
 import os
 import argparse
@@ -25,11 +26,10 @@ from PIL import Image
 from singa import device
 from singa import tensor
 from singa import converter
-from singa import layer
-from singa import net
 
-#for debug: print norm of each layer
-#net.verbose = True
+
+# for debug: print norm of each layer
+# net.verbose = True
 
 
 def convert_model(prototxt, caffemodel):
@@ -47,7 +47,7 @@ def read_image(img_path):
     # According to the VGG paper(Very Deep Convolutional Networks for
     # Large-Scale Image Recognition), the input images are zero-centered by
     # mean pixel(rather than mean image) substraction.
-    mean_RGB =[123.68, 116.779, 103.939]
+    mean_RGB = [123.68, 116.779, 103.939]
 
     img = Image.open(img_path)
     img = img.convert('RGB')
@@ -79,7 +79,7 @@ def predict(net, dev, synset_list, topk=5):
             print('Path is invalid')
             continue
         img = read_image(img_path)
-        x = tensor.from_numpy(img.astype(np.float32)[np.newaxis,:])
+        x = tensor.from_numpy(img.astype(np.float32)[np.newaxis, :])
         x.to_device(dev)
         y = net.predict(x)
         y.to_host()
@@ -91,7 +91,7 @@ def predict(net, dev, synset_list, topk=5):
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(
         description='Convert caffe vgg into singa. \
-            This tool only supports caffe model in current version(29-Nov-2016). \
+            This tool only supports caffe model from version as 29-Nov-2016. \
             You can use caffe tool to update previous model')
     parser.add_argument('model_txt', default='./vgg16.prototxt')
     parser.add_argument('model_bin', default='./vgg16.caffemodel')

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/char-rnn/sample.py
----------------------------------------------------------------------
diff --git a/examples/char-rnn/sample.py b/examples/char-rnn/sample.py
index 5b0b66a..eb745cf 100644
--- a/examples/char-rnn/sample.py
+++ b/examples/char-rnn/sample.py
@@ -15,22 +15,21 @@
 # limitations under the License.
 # =============================================================================
 '''Sample characters from the pre-trained model'''
+
 from __future__ import division
 from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
 from builtins import range
-from past.utils import old_div
 import sys
-import pickle as pickle
 import numpy as np
 import argparse
+try:
+    import pickle
+except ImportError:
+    import cPickle as pickle
 
-# sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
 from singa import layer
 from singa import tensor
 from singa import device
-from singa.proto import model_pb2
 
 
 def sample(model_path, nsamples=100, seed_text='', do_sample=True):
@@ -67,15 +66,15 @@ def sample(model_path, nsamples=100, seed_text='', do_sample=True):
             tx = tensor.from_numpy(x)
             tx.to_device(cuda)
             inputs = [tx, hx, cx]
-            outputs = rnn.forward(model_pb2.kEval, inputs)
-            y = dense.forward(model_pb2.kEval, outputs[0])
+            outputs = rnn.forward(False, inputs)
+            y = dense.forward(False, outputs[0])
             y = tensor.softmax(y)
             hx = outputs[1]
             cx = outputs[2]
         sys.stdout.write(seed_text)
     else:
         y = tensor.Tensor((1, vocab_size), cuda)
-        y.set_value(old_div(1.0, vocab_size))
+        y.set_value(1.0 / vocab_size)
 
     for i in range(nsamples):
         y.to_host()
@@ -90,8 +89,8 @@ def sample(model_path, nsamples=100, seed_text='', do_sample=True):
         tx = tensor.from_numpy(x)
         tx.to_device(cuda)
         inputs = [tx, hx, cx]
-        outputs = rnn.forward(model_pb2.kEval, inputs)
-        y = dense.forward(model_pb2.kEval, outputs[0])
+        outputs = rnn.forward(False, inputs)
+        y = dense.forward(False, outputs[0])
         y = tensor.softmax(y)
         hx = outputs[1]
         cx = outputs[2]

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/char-rnn/train.py
----------------------------------------------------------------------
diff --git a/examples/char-rnn/train.py b/examples/char-rnn/train.py
index 0eeeb35..240e574 100644
--- a/examples/char-rnn/train.py
+++ b/examples/char-rnn/train.py
@@ -19,31 +19,27 @@ The model is created following https://github.com/karpathy/char-rnn
 The train file could be any text file,
 e.g., http://cs.stanford.edu/people/karpathy/char-rnn/
 '''
+
+
 from __future__ import division
 from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
 from builtins import zip
 from builtins import range
 from builtins import object
-from past.utils import old_div
 import pickle as pickle
 import numpy as np
 import argparse
 
-# sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
 from singa import layer
 from singa import loss
 from singa import device
 from singa import tensor
 from singa import optimizer
 from singa import initializer
-from singa.proto import model_pb2
 from singa import utils
 
 
 class Data(object):
-
     def __init__(self, fpath, batch_size=32, seq_length=100, train_ratio=0.8):
         '''Data object for loading a plain text file.
 
@@ -59,16 +55,16 @@ class Data(object):
         self.idx_to_char = {i: ch for i, ch in enumerate(chars)}
         data = [self.char_to_idx[c] for c in self.raw_data]
         # seq_length + 1 for the data + label
-        nsamples = old_div(len(data), (1 + seq_length))
+        nsamples = len(data) // (1 + seq_length)
         data = data[0:nsamples * (1 + seq_length)]
         data = np.asarray(data, dtype=np.int32)
         data = np.reshape(data, (-1, seq_length + 1))
         # shuffle all sequences
         np.random.shuffle(data)
         self.train_dat = data[0:int(data.shape[0]*train_ratio)]
-        self.num_train_batch = old_div(self.train_dat.shape[0], batch_size)
+        self.num_train_batch = self.train_dat.shape[0] // batch_size
         self.val_dat = data[self.train_dat.shape[0]:]
-        self.num_test_batch = old_div(self.val_dat.shape[0], batch_size)
+        self.num_test_batch = self.val_dat.shape[0] // batch_size
         print('train dat', self.train_dat.shape)
         print('val dat', self.val_dat.shape)
 
@@ -102,7 +98,7 @@ def convert(batch, batch_size, seq_length, vocab_size, dev):
 
 
 def get_lr(epoch):
-    return old_div(0.001, float(1 << (old_div(epoch, 50))))
+    return 0.001 / float(1 << (epoch // 50))
 
 
 def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
@@ -152,30 +148,30 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
             inputs.append(tensor.Tensor())
             inputs.append(tensor.Tensor())
 
-            outputs = rnn.forward(model_pb2.kTrain, inputs)[0:-2]
+            outputs = rnn.forward(True, inputs)[0:-2]
             grads = []
             batch_loss = 0
             g_dense_w.set_value(0.0)
             g_dense_b.set_value(0.0)
             for output, label in zip(outputs, labels):
-                act = dense.forward(model_pb2.kTrain, output)
-                lvalue = lossfun.forward(model_pb2.kTrain, act, label)
+                act = dense.forward(True, output)
+                lvalue = lossfun.forward(True, act, label)
                 batch_loss += lvalue.l1()
                 grad = lossfun.backward()
                 grad /= batch_size
-                grad, gwb = dense.backward(model_pb2.kTrain, grad)
+                grad, gwb = dense.backward(True, grad)
                 grads.append(grad)
                 g_dense_w += gwb[0]
                 g_dense_b += gwb[1]
                 # print output.l1(), act.l1()
             utils.update_progress(
                 b * 1.0 / data.num_train_batch, 'training loss = %f' %
-                (old_div(batch_loss, seq_length)))
+                (batch_loss / seq_length))
             train_loss += batch_loss
 
             grads.append(tensor.Tensor())
             grads.append(tensor.Tensor())
-            g_rnn_w = rnn.backward(model_pb2.kTrain, grads)[1][0]
+            g_rnn_w = rnn.backward(True, grads)[1][0]
             dense_w, dense_b = dense.param_values()
             opt.apply_with_lr(epoch, get_lr(epoch), g_rnn_w, rnn_w, 'rnnw')
             opt.apply_with_lr(
@@ -184,8 +180,8 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
             opt.apply_with_lr(
                 epoch, get_lr(epoch),
                 g_dense_b, dense_b, 'dense_b')
-        print('\nEpoch %d, train loss is %f' % \
-            (epoch, train_loss / data.num_train_batch / seq_length))
+        print('\nEpoch %d, train loss is %f' %
+              (epoch, train_loss / data.num_train_batch / seq_length))
 
         eval_loss = 0
         for b in range(data.num_test_batch):
@@ -194,13 +190,12 @@ def train(data, max_epoch, hidden_size=100, seq_length=100, batch_size=16,
                                      data.vocab_size, cuda)
             inputs.append(tensor.Tensor())
             inputs.append(tensor.Tensor())
-            outputs = rnn.forward(model_pb2.kEval, inputs)[0:-2]
+            outputs = rnn.forward(False, inputs)[0:-2]
             for output, label in zip(outputs, labels):
-                output = dense.forward(model_pb2.kEval, output)
-                eval_loss += lossfun.forward(model_pb2.kEval,
-                                             output, label).l1()
-        print('Epoch %d, evaluation loss is %f' % \
-            (epoch, eval_loss / data.num_test_batch / seq_length))
+                output = dense.forward(True, output)
+                eval_loss += lossfun.forward(True, output, label).l1()
+        print('Epoch %d, evaluation loss is %f' %
+              (epoch, eval_loss / data.num_test_batch / seq_length))
 
         if (epoch + 1) % 30 == 0:
             # checkpoint the file model

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/cifar10/predict.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/predict.py b/examples/cifar10/predict.py
index 7cab4b9..1432e12 100644
--- a/examples/cifar10/predict.py
+++ b/examples/cifar10/predict.py
@@ -16,14 +16,13 @@
 # =============================================================================
 '''Predicting the labels for new images using the pre-trained alexnet model'''
 from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
 from builtins import range
-import pickle as pickle
+try:
+    import pickle
+except ImportError:
+    import cPickle as pickle
 import numpy as np
 
-# sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
-
 from singa import device
 from singa import tensor
 import alexnet

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/cifar10/resnet.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/resnet.py b/examples/cifar10/resnet.py
index 4b9bad0..fa4d1aa 100644
--- a/examples/cifar10/resnet.py
+++ b/examples/cifar10/resnet.py
@@ -20,16 +20,8 @@ The performance could be improved by tuning some hyper-parameters, including
 learning rate, weight decay, max_epoch, parameter initialization, etc.
 """
 from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
 from builtins import zip
 
-import pickle as pickle
-
-# sys.path.append(os.path.join(os.path.dirname(__file__), '../../build/python'))
-# use the python modules by installing py singa in build/python
-# pip install -e .
-
 from singa import layer
 from singa import initializer
 from singa import metric

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/cifar10/train.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/train.py b/examples/cifar10/train.py
index 9f90e58..9f1ffd2 100644
--- a/examples/cifar10/train.py
+++ b/examples/cifar10/train.py
@@ -20,14 +20,13 @@ includes 1 label & 3072 pixels.  3072 pixels are 3 channels of a 32x32 image
 """
 from __future__ import division
 from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
 from builtins import zip
 from builtins import str
 from builtins import range
-from past.utils import old_div
-
-import pickle
+try:
+    import pickle
+except ImportError:
+    import cPickle as pickle
 import numpy as np
 import os
 import argparse
@@ -93,7 +92,7 @@ def normalize_for_alexnet(train_x, test_x):
 
 
 def vgg_lr(epoch):
-    return old_div(0.1, float(1 << ((old_div(epoch, 25)))))
+    return 0.1 / float(1 << (epoch // 25))
 
 
 def alexnet_lr(epoch):
@@ -139,8 +138,8 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
     tx = tensor.Tensor((batch_size, 3, 32, 32), dev)
     ty = tensor.Tensor((batch_size,), dev, core_pb2.kInt)
     train_x, train_y, test_x, test_y = data
-    num_train_batch = old_div(train_x.shape[0], batch_size)
-    num_test_batch = old_div(test_x.shape[0], batch_size)
+    num_train_batch = train_x.shape[0] // batch_size
+    num_test_batch = test_x.shape[0] // batch_size
     idx = np.arange(train_x.shape[0], dtype=np.int32)
     for epoch in range(max_epoch):
         np.random.shuffle(idx)
@@ -160,7 +159,7 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
             utils.update_progress(b * 1.0 / num_train_batch,
                                   'training loss = %f, accuracy = %f' % (l, a))
         info = '\ntraining loss = %f, training accuracy = %f, lr = %f' \
-            % (old_div(loss, num_train_batch), old_div(acc, num_train_batch), get_lr(epoch))
+            % ((loss / num_train_batch), (acc / num_train_batch), get_lr(epoch))
         print(info)
 
         loss, acc = 0.0, 0.0
@@ -173,14 +172,14 @@ def train(data, net, max_epoch, get_lr, weight_decay, batch_size=100,
             loss += l
             acc += a
 
-        print('test loss = %f, test accuracy = %f' \
-            % (old_div(loss, num_test_batch), old_div(acc, num_test_batch)))
+        print('test loss = %f, test accuracy = %f' %
+              ((loss / num_test_batch), (acc / num_test_batch)))
     net.save('model', 20)  # save model params into checkpoint file
 
 if __name__ == '__main__':
     parser = argparse.ArgumentParser(description='Train dcnn for cifar10')
     parser.add_argument('model', choices=['vgg', 'alexnet', 'resnet', 'caffe'],
-            default='alexnet')
+                        default='alexnet')
     parser.add_argument('data', default='cifar-10-batches-py')
     parser.add_argument('--use_cpu', action='store_true')
     args = parser.parse_args()
@@ -196,7 +195,7 @@ if __name__ == '__main__':
         train((train_x, train_y, test_x, test_y), net, 160, alexnet_lr, 0.004,
               use_cpu=args.use_cpu)
         # for cifar10_quick_train_test.prototxt
-        #train((train_x, train_y, test_x, test_y), net, 18, caffe_lr, 0.004,
+        # train((train_x, train_y, test_x, test_y), net, 18, caffe_lr, 0.004,
         #      use_cpu=args.use_cpu)
     elif args.model == 'alexnet':
         train_x, test_x = normalize_for_alexnet(train_x, test_x)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/imagenet/resnet/serve.py
----------------------------------------------------------------------
diff --git a/examples/imagenet/resnet/serve.py b/examples/imagenet/resnet/serve.py
index fde06fe..4c7d897 100644
--- a/examples/imagenet/resnet/serve.py
+++ b/examples/imagenet/resnet/serve.py
@@ -1,8 +1,3 @@
-from __future__ import division
-from __future__ import print_function
-from builtins import str
-from builtins import range
-from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -19,20 +14,20 @@ from past.utils import old_div
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import os
+from __future__ import division
+from __future__ import print_function
+from builtins import str
+from builtins import range
+
 import sys
 import time
 import numpy as np
-import threading
 import traceback
-from scipy.misc import imread, imresize
 from argparse import ArgumentParser
 
 from singa import device
 from singa import tensor
-from singa import data
 from singa import image_tool
-from singa import metric
 from rafiki.agent import Agent, MsgType
 import model
 
@@ -40,11 +35,14 @@ tool = image_tool.ImageTool()
 num_augmentation = 10
 crop_size = 224
 mean = np.array([0.485, 0.456, 0.406])
-std = np.array([ 0.229, 0.224, 0.225])
+std = np.array([0.229, 0.224, 0.225])
+
+
 def image_transform(img):
     '''Input an image path and return a set of augmented images (type Image)'''
     global tool
-    return tool.load(img).resize_by_list([256]).crop5((crop_size, crop_size), 5).flip(2).get()
+    return tool.load(img).resize_by_list([256]).crop5((crop_size, crop_size),
+                                                      5).flip(2).get()
 
 
 def predict(net, images, num=10):
@@ -57,7 +55,7 @@ def predict(net, images, num=10):
     '''
     prob = net.predict(images)
     prob = tensor.to_numpy(prob)
-    prob = prob.reshape((old_div(images.shape[0], num), num, -1))
+    prob = prob.reshape(((images.shape[0] // num), num, -1))
     prob = np.average(prob, 1)
     return prob
 
@@ -76,7 +74,7 @@ def serve(net, label_map, dev, agent, topk=5):
         label_map: a list of food names, corresponding to the index in meta_file
     '''
 
-    images =tensor.Tensor((num_augmentation, 3, crop_size, crop_size), dev)
+    images = tensor.Tensor((num_augmentation, 3, crop_size, crop_size), dev)
     while True:
         msg, val = agent.pull()
         if msg is None:
@@ -86,8 +84,10 @@ def serve(net, label_map, dev, agent, topk=5):
         if msg.is_request():
             try:
                 # process images
-                im = [np.array(x.convert('RGB'), dtype=np.float32).transpose(2, 0, 1) for x in image_transform(val['image'])]
-                im = old_div(np.array(im), 256)
+                im = [np.array(x.convert('RGB'),
+                               dtype=np.float32).transpose(2, 0, 1)
+                      for x in image_transform(val['image'])]
+                im = np.array(im) / 255
                 im -= mean[np.newaxis, :, np.newaxis, np.newaxis]
                 im /= std[np.newaxis, :, np.newaxis, np.newaxis]
                 images.copy_from_numpy(im)
@@ -98,7 +98,8 @@ def serve(net, label_map, dev, agent, topk=5):
                 # prepare results
                 response = ""
                 for i in range(topk):
-                    response += "%s:%f <br/>" % (label_map[idx[i]], prob[idx[i]])
+                    response += "%s:%f <br/>" % (label_map[idx[i]],
+                                                 prob[idx[i]])
             except:
                 traceback.print_exc()
                 response = "sorry, system error during prediction."
@@ -117,6 +118,7 @@ def serve(net, label_map, dev, agent, topk=5):
             break
     print("server stop")
 
+
 def main():
     try:
         # Setup argument parser
@@ -126,8 +128,11 @@ def main():
         parser.add_argument("--use_cpu", action="store_true",
                             help="If set, load models onto CPU devices")
         parser.add_argument("--parameter_file", default="wrn-50-2.pickle")
-        parser.add_argument("--model", choices = ['resnet', 'wrn', 'preact', 'addbn'], default='wrn')
-        parser.add_argument("--depth", type=int, choices = [18, 34, 50, 101, 152, 200], default='50')
+        parser.add_argument("--model", choices=['resnet', 'wrn', 'preact',
+                                                'addbn'], default='wrn')
+        parser.add_argument("--depth", type=int, choices=[18, 34, 50, 101,
+                                                          152, 200],
+                            default='50')
 
         # Process arguments
         args = parser.parse_args()

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/examples/mnist/train.py
----------------------------------------------------------------------
diff --git a/examples/mnist/train.py b/examples/mnist/train.py
index 82d9a5a..88c9a44 100644
--- a/examples/mnist/train.py
+++ b/examples/mnist/train.py
@@ -1,9 +1,3 @@
-from __future__ import division
-from __future__ import print_function
-from future import standard_library
-standard_library.install_aliases()
-from builtins import range
-from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -20,23 +14,25 @@ from past.utils import old_div
 # See the License for the specific language governing permissions and
 # limitations under the License.
 # =============================================================================
+from __future__ import division
+from __future__ import print_function
+from builtins import range
 
 import numpy as np
 import os
 import gzip
 import argparse
-import pickle
+try:
+    import pickle
+except ImportError:
+    import cPickle as pickle
+
 from singa import initializer
-from singa import utils
 from singa import optimizer
 from singa import device
 from singa import tensor
 
 
-from singa.proto import core_pb2
-
-
-
 def load_train_data(file_path):
     f = gzip.open(file_path, 'rb')
     train_set, valid_set, test_set = pickle.load(f)
@@ -46,19 +42,18 @@ def load_train_data(file_path):
     return traindata, validdata
 
 
-
 def train(data_file, use_gpu, num_epoch=10, batch_size=100):
     print('Start intialization............')
     lr = 0.1   # Learning rate
-    weight_decay  = 0.0002
+    weight_decay = 0.0002
     hdim = 1000
     vdim = 784
     opt = optimizer.SGD(momentum=0.8, weight_decay=weight_decay)
 
     tweight = tensor.Tensor((vdim, hdim))
     tweight.gaussian(0.0, 0.1)
-    tvbias = tensor.from_numpy(np.zeros(vdim, dtype = np.float32))
-    thbias = tensor.from_numpy(np.zeros(hdim, dtype = np.float32))
+    tvbias = tensor.from_numpy(np.zeros(vdim, dtype=np.float32))
+    thbias = tensor.from_numpy(np.zeros(hdim, dtype=np.float32))
     opt = optimizer.SGD(momentum=0.5, weight_decay=weight_decay)
 
     print('Loading data ..................')
@@ -72,7 +67,7 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
     for t in [tweight, tvbias, thbias]:
         t.to_device(dev)
 
-    num_train_batch = old_div(train_x.shape[0], batch_size)
+    num_train_batch = train_x.shape[0] // batch_size
     print("num_train_batch = %d " % (num_train_batch))
     for epoch in range(num_epoch):
         trainerrorsum = 0.0
@@ -80,7 +75,7 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
         for b in range(num_train_batch):
             # positive phase
             tdata = tensor.from_numpy(
-                    train_x[(b * batch_size):((b + 1) * batch_size), : ])
+                    train_x[(b * batch_size):((b + 1) * batch_size), :])
             tdata.to_device(dev)
             tposhidprob = tensor.mult(tdata, tweight)
             tposhidprob.add_row(thbias)
@@ -100,14 +95,14 @@ def train(data_file, use_gpu, num_epoch=10, batch_size=100):
             error = tensor.sum(tensor.square((tdata - tnegdata)))
             trainerrorsum = error + trainerrorsum
 
-            tgweight = tensor.mult(tnegdata.T(), tneghidprob) -\
-                    tensor.mult(tdata.T(), tposhidprob)
+            tgweight = tensor.mult(tnegdata.T(), tneghidprob) \
+                - tensor.mult(tdata.T(), tposhidprob)
             tgvbias = tensor.sum(tnegdata, 0) - tensor.sum(tdata, 0)
             tghbias = tensor.sum(tneghidprob, 0) - tensor.sum(tposhidprob, 0)
 
-            opt.apply_with_lr(epoch, old_div(lr, batch_size), tgweight, tweight, 'w')
-            opt.apply_with_lr(epoch, old_div(lr, batch_size), tgvbias, tvbias, 'vb')
-            opt.apply_with_lr(epoch, old_div(lr, batch_size), tghbias, thbias, 'hb')
+            opt.apply_with_lr(epoch, lr / batch_size, tgweight, tweight, 'w')
+            opt.apply_with_lr(epoch, lr / batch_size, tgvbias, tvbias, 'vb')
+            opt.apply_with_lr(epoch, lr / batch_size, tghbias, thbias, 'hb')
 
         print('training errorsum = %f' % (trainerrorsum))
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/rafiki/agent.py
----------------------------------------------------------------------
diff --git a/python/rafiki/agent.py b/python/rafiki/agent.py
index 98d9b01..5dc820d 100644
--- a/python/rafiki/agent.py
+++ b/python/rafiki/agent.py
@@ -1,5 +1,3 @@
-from builtins import str
-from builtins import object
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,6 +15,9 @@ from builtins import object
 # specific language governing permissions and limitations
 # under the License.
 # =============================================================================
+from builtins import str
+from builtins import object
+
 from multiprocessing import Process, Queue
 from flask import Flask,request, send_from_directory, jsonify
 from flask_cors import CORS, cross_origin
@@ -38,15 +39,15 @@ class MsgType(object):
        return str(self) == str(target)
 
    def is_info(self):
-       return self.name.startswith('kInfo') 
+       return self.name.startswith('kInfo')
    def is_command(self):
-       return self.name.startswith('kCommand') 
+       return self.name.startswith('kCommand')
    def is_status(self):
-       return self.name.startswith('kStatus') 
+       return self.name.startswith('kStatus')
    def is_request(self):
-       return self.name.startswith('kRequest') 
+       return self.name.startswith('kRequest')
    def is_response(self):
-       return self.name.startswith('kResponse') 
+       return self.name.startswith('kResponse')
 
    @staticmethod
    def parse(name):
@@ -59,7 +60,7 @@ class MsgType(object):
            return MsgType.kCommandPause
        if name=='resume':
            return MsgType.kCommandResume
-       return MsgType.kCommand 
+       return MsgType.kCommand
 
 types =  ['kInfo','kInfoMetric',
            'kCommand','kCommandStop','kCommandPause','kCommandResume',
@@ -91,7 +92,7 @@ class Agent(object):
             if msg.is_request():
                 data = pickle.loads(data)
             return msg,data
-        return None,None 
+        return None,None
 
     def push(self,msg,value):
         self.info_queue.put((msg,value))
@@ -165,10 +166,10 @@ def getTopKData():
         return failure("Internal Error")
     return success(data_[-k:])
 
-@app.route("/api", methods=['POST'])                                                                  
-@cross_origin()                                                                                           
+@app.route("/api", methods=['POST'])
+@cross_origin()
 def api():
-    global info_queue_,command_queue_ 
+    global info_queue_,command_queue_
     try:
         files=transformFile(request.files)
         values = CombinedMultiDict([request.args,request.form,files])
@@ -177,20 +178,20 @@ def api():
         msg,response=getDataFromInfoQueue(True)
         deleteFiles(files)
         return response
-    except:                                                                            
+    except:
         traceback.print_exc()
         return failure("Internal Error")
 
-@app.route("/command/<name>", methods=['GET','POST'])                                                                  
-@cross_origin()                                                                                           
+@app.route("/command/<name>", methods=['GET','POST'])
+@cross_origin()
 def command(name):
-    global info_queue_,command_queue_ 
+    global info_queue_,command_queue_
     try:
         command=MsgType.get_command(name)
         command_queue_.put((command,""))
         msg,response=getDataFromInfoQueue(True)
         return response
-    except:                                                                            
+    except:
         traceback.print_exc()
         return failure("Internal Error")
 
@@ -203,19 +204,20 @@ def failure(message):
     res = dict(result="message", message=message)
     return jsonify(res)
 
+
 def transformFile(files):
     result= MultiDict([])
-    for f in list(files.keys()):
+    for f in files:
         file = files[f]
         unique_filename = str(uuid.uuid4())+secure_filename(file.filename)
-        filepath=os.path.join(os.getcwd(),unique_filename)
+        filepath=os.path.join(os.getcwd(), unique_filename)
         file.save(filepath)
-        result.add(f,filepath)
+        result.add(f, filepath)
     return result
 
+
 def deleteFiles(files):
-    for f in list(files.keys()):
-        filepath = files[f]    
+    for f in files:
+        filepath = files[f]
         os.remove(filepath)
-        #print "remove",filepath
     return

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/setup.py.in
----------------------------------------------------------------------
diff --git a/python/setup.py.in b/python/setup.py.in
index f667ae5..7a9f2c6 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -67,10 +67,9 @@ setup(
         'flask_cors>=3.0.2',
         'pillow>=2.3.0',
         'future',
-	'xmlrunner',
-	'tqdm',
-	'ipywidgets',
-	'matplotlib',
+        'xmlrunner',
+        'tqdm',
+        'ipywidgets',
         ],
 
     #List additional groups of dependencies here (e.g. development

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/command.py
----------------------------------------------------------------------
diff --git a/python/singa/command.py b/python/singa/command.py
deleted file mode 100644
index 90c51cc..0000000
--- a/python/singa/command.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements.  See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership.  The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License.  You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied.  See the License for the
-# specific language governing permissions and limitations
-# under the License.
-# =============================================================================
-
-'''
-This script is the main entrance for user to run singa inside a model workspace
-
-To use this script, user sudo install these dependencies: flask pillow and protobuf
-'''
-from __future__ import print_function
-
-from future import standard_library
-standard_library.install_aliases()
-from builtins import str
-import sys, glob, os, random, shutil, time
-from flask import Flask, request, redirect, url_for
-import numpy as np
-import configparser
-import urllib.request, urllib.parse, urllib.error, traceback
-
-
-from argparse import ArgumentParser
-from argparse import RawDescriptionHelpFormatter
-sys.path.append(os.getcwd())
-
-__all__ = []
-__version__ = 0.1
-__date__ = '2016-07-20'
-__updated__ = '2016-07-20'
-__shortdesc__ = '''
-welcome to singa
-'''
-
-app = Flask(__name__)
-config = configparser.RawConfigParser()
-service = {}
-data_path = "data_"
-parameter_path = "parameter_"
-
-debug = False
-
-class CLIError(Exception):
-    '''Generic exception to raise and log different fatal errors.'''
-    def __init__(self, msg):
-        super(CLIError).__init__(type(self))
-        self.msg = "E: %s" % msg
-    def __str__(self):
-        return self.msg
-    def __unicode__(self):
-        return self.msg
-
-def main(argv=None): # IGNORE:C0111
-    '''Command line options.'''
-
-    from . import device
-
-    if argv is None:
-        argv = sys.argv
-    else:
-        sys.argv.extend(argv)
-
-    program_name = os.path.basename(sys.argv[0])
-    program_version = "v%s" % __version__
-    program_build_date = str(__updated__)
-    program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
-    program_shortdesc = __shortdesc__
-    program_license = '''%s
-
-  Created by dbsystem group on %s.
-  Copyright 2016 NUS School of Computing. All rights reserved.
-
-  Licensed under the Apache License 2.0
-  http://www.apache.org/licenses/LICENSE-2.0
-
-  Distributed on an "AS IS" basis without warranties
-  or conditions of any kind, either express or implied.
-
-USAGE
-''' % (program_shortdesc, str(__date__))
-
-    global debug
-
-    try:
-        # Setup argument parser
-        parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
-        parser.add_argument("-p", "--port", dest="port", default=5000, help="the port to listen to, default is 5000")
-        parser.add_argument("-param", "--parameter", dest="parameter",  help="the parameter file path to be loaded")
-        parser.add_argument("-D", "--debug", dest="debug", action="store_true", help="whether need to debug")
-        parser.add_argument("-R", "--reload", dest="reload_data", action="store_true", help="whether need to reload data")
-        parser.add_argument("-C", "--cpu", dest="use_cpu", action="store_true", help="Using cpu or not, default is using gpu")
-        parser.add_argument("-m", "--mode", dest="mode", choices=['train','test','serve'], default='serve', help="On Which mode (train,test,serve) to run singa")
-        parser.add_argument('-V', '--version', action='version', version=program_version_message)
-
-        # Process arguments
-        args = parser.parse_args()
-
-        port = args.port
-        parameter_file = args.parameter
-        mode = args.mode
-        need_reload = args.reload_data
-        use_cpu = args.use_cpu
-        debug = args.debug
-
-        #prepare data files
-        config.read('file.cfg')
-        file_prepare(need_reload)
-
-
-        import network as net
-        model = net.create()
-
-        #load parameter
-        parameter_file=get_parameter(parameter_file)
-
-        if parameter_file:
-            print("load parameter file: %s" % parameter_file)
-            model.load(parameter_file)
-
-        if use_cpu:
-            raise CLIError("Currently cpu is not support!")
-        else:
-            print("runing with gpu")
-            d = device.create_cuda_gpu()
-
-        model.to_device(d)
-
-        if mode == "serve":
-            print("runing singa in serve mode, listen to  port: %s " % port)
-            global service
-            from serve import Service
-            service =Service(model,d)
-
-            app.debug = debug
-            app.run(host='0.0.0.0', port= port)
-        elif mode == "train":
-            print("runing singa in train mode")
-            global trainer
-            from train import Trainer
-            trainer= Trainer(model,d)
-            if not parameter_file:
-                trainer.initialize()
-            trainer.train()
-        else:
-            raise CLIError("Currently only serve mode is surpported!")
-        return 0
-    except KeyboardInterrupt:
-        ### handle keyboard interrupt ###
-        return 0
-    except Exception as e:
-        if debug:
-            traceback.print_exc()
-            raise(e)
-        indent = len(program_name) * " "
-        sys.stderr.write(program_name + ": " + str(e) + "\n")
-        sys.stderr.write(indent + "  for help use --help \n\n")
-        return 2
-
-def file_prepare(reload_data=False):
-    '''
-        download all files and generate data.py
-    '''
-    if not reload_data and os.path.exists("data_.py"):
-        return
-
-    print("download file")
-    #clean data
-    shutil.rmtree("data_.py",ignore_errors=True)
-    shutil.rmtree("data_",ignore_errors=True)
-
-    data_py=open("data_.py",'w')
-    data_py.write("#%s" % "This file is Generated by SINGA, please don't edit\n\n")
-    if config.has_section("data"):
-        file_list = config.items("data")
-        #download files
-        for f in file_list:
-            name,path=download_file(f[0],f[1],data_path)
-            data_py.write("%s=\"%s\"\n" % (name,path))
-
-    data_py.flush()
-    data_py.close()
-
-    if config.has_section("parameter"):
-        parameter_list = config.items("parameter")
-        for p in parameter_list:
-            download_file(p[0],p[1],parameter_path)
-
-def download_file(name,path,dest):
-    '''
-    download one file to dest
-    '''
-    if not os.path.exists(dest):
-        os.makedirs(dest)
-    if (path.startswith('http')):
-        file_name = path.split('/')[-1]
-        target = os.path.join(dest,file_name)
-        urllib.request.urlretrieve(path,target)
-    return name,target
-
-
-def get_parameter(file_name=None):
-    '''
-    get the paticular file name or get the last parameter file
-    '''
-    if not os.path.exists(parameter_path):
-        os.makedirs(parameter_path)
-        return
-
-    if file_name:
-	return os.path.join(parameter_path,file_name)
-
-    parameter_list = [ os.path.join(parameter_path,f) for f in os.listdir(parameter_path)]
-    if len(parameter_list)==0:
-        return
-    parameter_list.sort()
-
-    return parameter_list[-1]
-
-@app.route("/")
-def index():
-    return "Hello SINGA User!"
-
-@app.route('/predict', methods=['POST'])
-def predict():
-    if request.method == 'POST':
-        try:
-            response=service.serve(request)
-        except Exception as e:
-            return e
-        return response
-    return "error, should be post request"

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/image_tool.py
----------------------------------------------------------------------
diff --git a/python/singa/image_tool.py b/python/singa/image_tool.py
index 529f73b..534d3e2 100644
--- a/python/singa/image_tool.py
+++ b/python/singa/image_tool.py
@@ -32,7 +32,6 @@ from __future__ import division
 
 from builtins import range
 from builtins import object
-from past.utils import old_div
 import random
 import numpy as np
 from PIL import Image, ImageEnhance
@@ -73,7 +72,7 @@ def crop(img, patch, position):
     elif position == 'right_bottom':
         left, upper = img.size[0]-patch[0], img.size[1]-patch[1]
     elif position == 'center':
-        left, upper = old_div((img.size[0]-patch[0]),2), old_div((img.size[1]-patch[1]),2)
+        left, upper = (img.size[0]-patch[0]) // 2, (img.size[1]-patch[1]) // 2
     else:
         raise Exception('position is wrong')
 
@@ -96,8 +95,8 @@ def crop_and_resize(img, patch, position):
         left, upper = 0, 0
         right, bottom = size[1], size[1]
     elif position == 'center':
-        left, upper = old_div((size[0]-size[1]),2), 0
-        right, bottom = old_div((size[0]+size[1]),2), size[1]
+        left, upper = (size[0]-size[1]) // 2, 0
+        right, bottom = (size[0]+size[1]) // 2, size[1]
     elif position == 'right':
         left, upper = size[0]-size[1], 0
         right, bottom = size[0], size[1]
@@ -105,8 +104,8 @@ def crop_and_resize(img, patch, position):
         left, upper = 0, 0
         right, bottom = size[0], size[0]
     elif position == 'middle':
-        left, upper = 0, old_div((size[1]-size[0]),2)
-        right, bottom = size[0], old_div((size[1]+size[0]),2)
+        left, upper = 0, (size[1]-size[0]) // 2
+        right, bottom = size[0], (size[1]+size[0]) // 2
     elif position == 'bottom':
         left, upper = 0, size[1]-size[0]
         right, bottom = size[0], size[1]

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/initializer.py
----------------------------------------------------------------------
diff --git a/python/singa/initializer.py b/python/singa/initializer.py
index 5d5f31e..cb2f5a0 100644
--- a/python/singa/initializer.py
+++ b/python/singa/initializer.py
@@ -27,8 +27,6 @@ Example usages::
     initializer.uniform(x, 3, 0)  # use only fan_in
 '''
 from __future__ import division
-
-from past.utils import old_div
 import math
 
 
@@ -91,7 +89,7 @@ def xavier(t):
         t (Tensor): the parater tensor
     '''
 
-    scale = math.sqrt(old_div(6.0, (t.shape[0] + t.shape[1])))
+    scale = math.sqrt(6.0 / (t.shape[0] + t.shape[1]))
     t.uniform(-scale, scale)
 
 
@@ -104,7 +102,7 @@ def glorot(t):
     Args:
         t (Tensor): the parater tensor
     '''
-    scale = math.sqrt(old_div(2.0, (t.shape[0] + t.shape[1])))
+    scale = math.sqrt(2.0 / (t.shape[0] + t.shape[1]))
     t.gaussian(0, 1)
     t *= scale
 
@@ -121,4 +119,4 @@ def msra(t):
     Args:
         t (Tensor): the parater tensor
     '''
-    t.gaussian(0, math.sqrt(old_div(2.0, t.shape[0])))
+    t.gaussian(0, math.sqrt(2.0 / t.shape[0]))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/layer.py
----------------------------------------------------------------------
diff --git a/python/singa/layer.py b/python/singa/layer.py
index 153768b..8a32279 100644
--- a/python/singa/layer.py
+++ b/python/singa/layer.py
@@ -51,6 +51,7 @@ from builtins import str
 from builtins import range
 from builtins import object
 from builtins import set
+
 from . import singa_wrap
 from .proto import model_pb2
 from . import tensor

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/loss.py
----------------------------------------------------------------------
diff --git a/python/singa/loss.py b/python/singa/loss.py
index 800a113..2c86146 100644
--- a/python/singa/loss.py
+++ b/python/singa/loss.py
@@ -36,14 +36,11 @@ Example usage::
 '''
 from __future__ import division
 from __future__ import absolute_import
-
-
-from past.utils import old_div
 from builtins import object
+
 from . import singa_wrap as singa
-from .proto import model_pb2
 from . import tensor
-import numpy as np
+from .proto import model_pb2
 
 
 class Loss(object):
@@ -160,7 +157,7 @@ class SigmoidCrossEntropy(Loss):
             dx = pi - yi.
         '''
         assert self.truth is not None, 'must call forward in a prior'
-        dx =  self.prob - self.truth
+        dx = self.prob - self.truth
         self.truth = None
         return dx
 
@@ -214,4 +211,4 @@ class SquaredError(Loss):
         Returns:
             a float value as the averaged error
         '''
-        return old_div(tensor.sum(tensor.square(x - y) * 0.5), x.size())
+        return tensor.sum(tensor.square(x - y)) * 0.5 / x.size()

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/metric.py
----------------------------------------------------------------------
diff --git a/python/singa/metric.py b/python/singa/metric.py
index 8495c0c..893b139 100644
--- a/python/singa/metric.py
+++ b/python/singa/metric.py
@@ -37,10 +37,9 @@ Example usage::
 from __future__ import division
 from __future__ import absolute_import
 
-
 from builtins import range
-from past.utils import old_div
 from builtins import object
+
 from . import singa_wrap as singa
 from . import tensor
 import numpy as np
@@ -92,8 +91,6 @@ class Accuracy(Metric):
         self.swig_metric = singa.Accuracy()
 
 
-
-
 class Precision(Metric):
     '''Make the top-k labels of max probability as the prediction
 
@@ -102,8 +99,6 @@ class Precision(Metric):
     def __init__(self, top_k):
         self.top_k = top_k
 
-
-
     def forward(self, x, y):
         '''Compute the precision for each sample.
 
@@ -124,17 +119,17 @@ class Precision(Metric):
         x_np = tensor.to_numpy(x)
         y_np = tensor.to_numpy(y)
 
-        pred_np = np.argsort(-x_np)[:, 0:self.top_k] #Sort in descending order
+        pred_np = np.argsort(-x_np)[:, 0:self.top_k]  # Sort in descending order
 
         prcs_np = np.zeros(pred_np.shape[0], dtype=np.float32)
 
         for i in range(pred_np.shape[0]):
-            #groundtruth labels
+            # groundtruth labels
             label_np = np.argwhere(y_np[i])
 
-            #Num of common labels among prediction and groundtruth
+            # num of common labels among prediction and groundtruth
             num_intersect = np.intersect1d(pred_np[i], label_np).size
-            prcs_np[i] = old_div(num_intersect, float(self.top_k))
+            prcs_np[i] = num_intersect / float(self.top_k)
 
         precision = tensor.from_numpy(prcs_np)
 
@@ -144,7 +139,6 @@ class Precision(Metric):
 
         return precision
 
-
     def evaluate(self, x, y):
         '''Compute the averaged precision over all samples.
 
@@ -166,7 +160,6 @@ class Recall(Metric):
     def __init__(self, top_k):
         self.top_k = top_k
 
-
     def forward(self, x, y):
         '''Compute the recall for each sample.
 
@@ -187,17 +180,17 @@ class Recall(Metric):
         x_np = tensor.to_numpy(x)
         y_np = tensor.to_numpy(y)
 
-        pred_np = np.argsort(-x_np)[:, 0:self.top_k] #Sort in descending order
+        pred_np = np.argsort(-x_np)[:, 0:self.top_k]  # Sort in descending order
 
         recall_np = np.zeros(pred_np.shape[0], dtype=np.float32)
 
         for i in range(pred_np.shape[0]):
-            #Return the index of non-zero dimension of i-th sample
+            # Return the index of non-zero dimension of i-th sample
             label_np = np.argwhere(y_np[i])
 
-            #Num of common labels among prediction and groundtruth
+            # Num of common labels among prediction and groundtruth
             num_intersect = np.intersect1d(pred_np[i], label_np).size
-            recall_np[i] = old_div(float(num_intersect), label_np.size)
+            recall_np[i] = float(num_intersect) / label_np.size
 
         recall = tensor.from_numpy(recall_np)
 
@@ -207,7 +200,6 @@ class Recall(Metric):
 
         return recall
 
-
     def evaluate(self, x, y):
         '''Compute the averaged precision over all samples.
 
@@ -218,4 +210,4 @@ class Recall(Metric):
             a float value for the averaged metric
         '''
 
-        return tensor.average(self.forward(x,y))
+        return tensor.average(self.forward(x, y))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/net.py
----------------------------------------------------------------------
diff --git a/python/singa/net.py b/python/singa/net.py
index a53fc68..501b8bc 100644
--- a/python/singa/net.py
+++ b/python/singa/net.py
@@ -56,19 +56,22 @@ Example usages::
 from __future__ import print_function
 from __future__ import absolute_import
 
-from future import standard_library
-standard_library.install_aliases()
 from builtins import zip
 from builtins import str
 from builtins import object
+import os
+
 from .proto.model_pb2 import kTrain, kEval
 from .__init__ import __version__
 from . import tensor
 from . import layer
 from . import snapshot
-import pickle as pickle
 
-import os
+try:
+    import pickle
+except ImportError:
+    import cPickle as pickle
+
 
 '''For display training information, e.g L1 value of layer data'''
 verbose = False

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/optimizer.py
----------------------------------------------------------------------
diff --git a/python/singa/optimizer.py b/python/singa/optimizer.py
index 54b81e8..a86c537 100644
--- a/python/singa/optimizer.py
+++ b/python/singa/optimizer.py
@@ -34,13 +34,14 @@ Example usage::
 from __future__ import division
 from __future__ import absolute_import
 
-from past.utils import old_div
 from builtins import object
 import math
+
 from . import singa_wrap as singa
 from . import tensor
 from .proto import model_pb2
 
+
 class Optimizer(object):
     '''The base python optimizer class.
 
@@ -213,7 +214,8 @@ class SGD(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor,
+                       value.singa_tensor)
         return value
 
 
@@ -241,7 +243,8 @@ class Nesterov(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr, name.encode(), grad.singa_tensor,
+                       value.singa_tensor)
         return value
 
 
@@ -272,7 +275,8 @@ class RMSProp(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(step, lr,  name.encode(), grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(step, lr,  name.encode(), grad.singa_tensor,
+                       value.singa_tensor)
         return value
 
 
@@ -302,7 +306,8 @@ class AdaGrad(Optimizer):
         grad = self.apply_regularizer_constraint(epoch, value, grad, name, step)
         if name is not None and name in self.learning_rate_multiplier:
             lr = lr * self.learning_rate_multiplier[name]
-        self.opt.Apply(epoch, lr,  name.encode(), grad.singa_tensor, value.singa_tensor)
+        self.opt.Apply(epoch, lr,  name.encode(), grad.singa_tensor,
+                       value.singa_tensor)
         return value
 
 
@@ -437,5 +442,5 @@ class L2Constraint(Constraint):
 
     def apply(self, epoch, value, grad, step=-1):
         nrm = grad.l2()
-        grad *= old_div(self.threshold, nrm)
+        grad *= self.threshold / nrm
         return grad

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/python/singa/tensor.py
----------------------------------------------------------------------
diff --git a/python/singa/tensor.py b/python/singa/tensor.py
index 144ed61..10ff01b 100644
--- a/python/singa/tensor.py
+++ b/python/singa/tensor.py
@@ -57,10 +57,10 @@ from __future__ import division
 from __future__ import print_function
 from __future__ import absolute_import
 
-from past.utils import old_div
 from builtins import object
 import numpy as np
 from functools import reduce
+
 from .proto import core_pb2
 from . import singa_wrap as singa
 from . import device as pydevice
@@ -68,6 +68,7 @@ from . import device as pydevice
 int32 = core_pb2.kInt
 float32 = core_pb2.kFloat32
 
+
 class Tensor(object):
     '''Create a Py Tensor, which wraps a swig converted Tensor from CPP Tensor
 
@@ -766,7 +767,7 @@ def average(t, axis=None):
     if t.ndim() > 1:
         return _call_singa_func(singa.Average, t.singa_tensor, axis)
     else:
-        return old_div(singa.SumAsFloat(t.singa_tensor), t.size())
+        return singa.SumAsFloat(t.singa_tensor) / t.size()
 
 
 def softmax(t, out=None):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/test/python/test_loss.py
----------------------------------------------------------------------
diff --git a/test/python/test_loss.py b/test/python/test_loss.py
index eb06b81..31784ce 100644
--- a/test/python/test_loss.py
+++ b/test/python/test_loss.py
@@ -1,5 +1,3 @@
-from __future__ import division
-from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -17,9 +15,9 @@ from past.utils import old_div
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import division
 
 import unittest
-
 import numpy as np
 
 from singa import loss
@@ -47,7 +45,7 @@ class TestLoss(unittest.TestCase):
         sig.backward()
         l2 = sig.evaluate(True, self.x, self.y)
 
-        p = old_div(1.0, (1 + np.exp(-self.x_np)))
+        p = 1.0 / (1 + np.exp(-self.x_np))
         l = - (self.y_np * np.log(p) + (1-self.y_np) * np.log(1-p))
         self.assertAlmostEqual(l1.l1(), l2)
         self.assertAlmostEqual(l1.l1(), np.average(l))

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/test/python/test_metric.py
----------------------------------------------------------------------
diff --git a/test/python/test_metric.py b/test/python/test_metric.py
index 8a22372..80e2b7b 100644
--- a/test/python/test_metric.py
+++ b/test/python/test_metric.py
@@ -1,5 +1,3 @@
-from __future__ import division
-from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -17,9 +15,9 @@ from past.utils import old_div
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import division
 
 import unittest
-
 import numpy as np
 
 from singa import metric
@@ -30,57 +28,55 @@ class TestPrecision(unittest.TestCase):
     def setUp(self):
         x_np = np.asarray([[0.7, 0.2, 0.1],
                            [0.2, 0.4, 0.5],
-                           [0.2,0.4,0.4]],
+                           [0.2, 0.4, 0.4]],
                           dtype=np.float32)
 
         y_np = np.asarray([[1, 0, 1],
                            [0, 1, 1],
                            [1, 0, 0]],
-                           dtype=np.int32)
+                          dtype=np.int32)
 
         self.prcs = metric.Precision(top_k=2)
         self.x = tensor.from_numpy(x_np)
         self.y = tensor.from_numpy(y_np)
 
-
     def test_forward(self):
-        p = self.prcs.forward(self.x,self.y)
+        p = self.prcs.forward(self.x, self.y)
         self.assertAlmostEqual(tensor.to_numpy(p)[0], 0.5)
         self.assertAlmostEqual(tensor.to_numpy(p)[1], 1)
         self.assertAlmostEqual(tensor.to_numpy(p)[2], 0)
 
-
     def test_evaluate(self):
-        e = self.prcs.evaluate(self.x,self.y)
-        self.assertAlmostEqual(e, old_div((0.5 + 1 + 0), 3))
+        e = self.prcs.evaluate(self.x, self.y)
+        self.assertAlmostEqual(e, (0.5 + 1 + 0) / 3)
+
 
 class TestRecall(unittest.TestCase):
     def setUp(self):
         x_np = np.asarray([[0.7, 0.2, 0.1],
                            [0.2, 0.4, 0.5],
-                           [0.2,0.4,0.4]],
+                           [0.2, 0.4, 0.4]],
                           dtype=np.float32)
 
         y_np = np.asarray([[1, 0, 1],
                            [1, 1, 1],
                            [1, 0, 0]],
-                           dtype=np.int32)
+                          dtype=np.int32)
 
         self.recall = metric.Recall(top_k=2)
         self.x = tensor.from_numpy(x_np)
         self.y = tensor.from_numpy(y_np)
 
-
     def test_forward(self):
-        r = self.recall.forward(self.x,self.y)
+        r = self.recall.forward(self.x, self.y)
         self.assertAlmostEqual(tensor.to_numpy(r)[0], 0.5)
-        self.assertAlmostEqual(tensor.to_numpy(r)[1], old_div(2.0, 3))
+        self.assertAlmostEqual(tensor.to_numpy(r)[1], 2.0 / 3)
         self.assertAlmostEqual(tensor.to_numpy(r)[2], 0)
 
-
     def test_evaluate(self):
-        e = self.recall.evaluate(self.x,self.y)
-        self.assertAlmostEqual(e, old_div((0.5 + old_div(2.0, 3) + 0), 3))
+        e = self.recall.evaluate(self.x, self.y)
+        self.assertAlmostEqual(e, (0.5 + (2.0 / 3) + 0) / 3)
+
 
 if __name__ == '__main__':
     unittest.main()

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/test/python/test_net.py
----------------------------------------------------------------------
diff --git a/test/python/test_net.py b/test/python/test_net.py
index afabc0d..8522f15 100644
--- a/test/python/test_net.py
+++ b/test/python/test_net.py
@@ -1,6 +1,3 @@
-from __future__ import division
-from builtins import zip
-from past.utils import old_div
 #
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
@@ -18,6 +15,8 @@ from past.utils import old_div
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #
+from __future__ import division
+from builtins import zip
 
 import unittest
 import math
@@ -44,7 +43,7 @@ class TestFeedForwardNet(unittest.TestCase):
         y.set_value(0)
         out, _ = ffn.evaluate(x, y)
         self.assertAlmostEqual(out * 3,
-                               - math.log(old_div(1.0,(1+math.exp(1)))) -
+                               - math.log(1.0 / (1+math.exp(1))) -
                                math.log(0.5) - math.log(0.5),
                                5)
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/test/python/test_optimizer.py
----------------------------------------------------------------------
diff --git a/test/python/test_optimizer.py b/test/python/test_optimizer.py
index 11374f5..f5c5471 100644
--- a/test/python/test_optimizer.py
+++ b/test/python/test_optimizer.py
@@ -1,7 +1,3 @@
-from __future__ import division
-from builtins import zip
-from builtins import range
-from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -19,6 +15,10 @@ from past.utils import old_div
 # specific language governing permissions and limitations
 # under the License.
 # =============================================================================
+from __future__ import division
+from builtins import zip
+from builtins import range
+
 import unittest
 import math
 import numpy as np
@@ -35,7 +35,7 @@ if singa_wrap.USE_CUDA:
 
 def np_adam(plist, glist, mlist, vlist, lr, t, b1=0.9, b2=0.999):
     for p, g, m, v in zip(plist, glist, mlist, vlist):
-        m *=b1
+        m *= b1
         m += (1-b1) * g
         v *= b2
         v += (1-b2) * g * g
@@ -110,7 +110,7 @@ class TestOptimizer(unittest.TestCase):
         cons = opt.L2Constraint(threshold)
         cons.apply(0, self.W, self.g)
         g = tensor.to_numpy(self.g)
-        nrm = old_div(np.linalg.norm(self.np_g), self.np_g.size)
+        nrm = np.linalg.norm(self.np_g) / self.np_g.size
         for i in range(g.size):
             self.assertAlmostEqual(g[i], self.np_g[i] * threshold / nrm)
 
@@ -122,7 +122,7 @@ class TestOptimizer(unittest.TestCase):
         cons.apply(0, self.W, self.g)
         self.g.to_host()
         g = tensor.to_numpy(self.g)
-        nrm = old_div(np.linalg.norm(self.np_g), self.np_g.size)
+        nrm = np.linalg.norm(self.np_g) / self.np_g.size
         for i in range(g.size):
             self.assertAlmostEqual(g[i], self.np_g[i] * threshold / nrm)
 

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/test/python/test_tensor.py
----------------------------------------------------------------------
diff --git a/test/python/test_tensor.py b/test/python/test_tensor.py
index 3f86899..dc3ff13 100644
--- a/test/python/test_tensor.py
+++ b/test/python/test_tensor.py
@@ -1,5 +1,3 @@
-from __future__ import division
-from past.utils import old_div
 # Licensed to the Apache Software Foundation (ASF) under one
 # or more contributor license agreements.  See the NOTICE file
 # distributed with this work for additional information
@@ -17,6 +15,7 @@ from past.utils import old_div
 # specific language governing permissions and limitations
 # under the License.
 # =============================================================================
+from __future__ import division
 
 import math
 import unittest
@@ -152,7 +151,7 @@ class TestTensorMethods(unittest.TestCase):
     def test_rdiv(self):
         x = tensor.Tensor((3,))
         x.set_value(1)
-        y = old_div(2, x)
+        y = 2 / x
         self.assertEqual(tensor.average(y), 2.)
 
     def test_numpy_convert(self):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/01b7a74b/tool/opencl/clsrc_to_str.py
----------------------------------------------------------------------
diff --git a/tool/opencl/clsrc_to_str.py b/tool/opencl/clsrc_to_str.py
index 8ca94a0..9faea7d 100755
--- a/tool/opencl/clsrc_to_str.py
+++ b/tool/opencl/clsrc_to_str.py
@@ -22,19 +22,21 @@
 This file is executed only if .cl files are updated.
 It is executed in the ROOT folder of SINGA source repo.
 '''
-
+from future.utils import iteritems
 
 distribution = "./src/core/tensor/distribution.cl"
 tensormath = "./src/core/tensor/tensor_math_opencl.cl"
 im2col = "./src/model/layer/im2col.cl"
 pooling = "./src/model/layer/pooling.cl"
+files = {"distribution_str": distribution, "tensormath_str": tensormath,
+         "im2col_str": im2col, "pooling_str": pooling}
 
-files = {"distribution_str" : distribution, "tensormath_str" : tensormath, "im2col_str" : im2col, "pooling_str" : pooling}
 
 if __name__ == "__main__":
     fullpath = './src/core/device/opencl_func.h'
     with open(fullpath, 'w') as fout:
-        fout.write("// This file is auto-generated by tool/opencl/clsrc_to_str, do not edit manually.\n")
+        fout.write("// This file is auto-generated by tool/opencl/clsrc_to_str."
+                   " do not edit manually.\n")
         license = """
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -57,7 +59,7 @@ if __name__ == "__main__":
         fout.write(license)
         fout.write("#include <string>\n\n")
         fout.write("namespace singa {\n namespace opencl {\n")
-        for name, path in list(files.items()):
+        for name, path in iteritems(files):
             with open(path, 'r') as fin:
                 src = fin.read()
                 src = repr(src)


[08/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bfeb6127/doc/en/docs/notebook/mlp.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/mlp.ipynb b/doc/en/docs/notebook/mlp.ipynb
index 5dcbe28..de5fae5 100755
--- a/doc/en/docs/notebook/mlp.ipynb
+++ b/doc/en/docs/notebook/mlp.ipynb
@@ -12,11 +12,12 @@
   {
    "cell_type": "code",
    "execution_count": 1,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [],
    "source": [
+    "from __future__ import print_function\n",
+    "from builtins import range\n",
+    "\n",
     "import numpy as np\n",
     "import matplotlib.pyplot as plt\n",
     "%matplotlib inline"
@@ -33,7 +34,7 @@
    "cell_type": "code",
    "execution_count": 2,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -69,7 +70,7 @@
    "cell_type": "code",
    "execution_count": 3,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -109,15 +110,13 @@
   {
    "cell_type": "code",
    "execution_count": 5,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD8CAYAAAB+UHOxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXt4VNW9sN9FkslkMkhUVFDgiApoW2prQdt6qZfWC3gj\nB63SiooKavUrVU6PRwU88OmxWq1VW6VVo9BQbau0qKD1gkLVU8B+4qWCCmJBvAICSSYJSdb3x5pN\ndib7svbM3nNJ1vs8+5nbnrXX3rNn/db6XYWUEoPBYDD0PvoUugMGg8FgKAxGABgMBkMvxQgAg8Fg\n6KUYAWAwGAy9FCMADAaDoZdiBIDBYDD0UowAMBgMhl6KEQAGg8HQSzECwGAwGHop5YXugBf9+/eX\n+++/f6G7YTAYDCXDq6+++rmUci+dfYtaAOy///6sXLmy0N0wGAyGkkEI8YHuvkYFZDAYDL0UIwAM\nBoOhl2IEgMFgMPRSitoG4MTOnTvZuHEjzc3Nhe5KSROPxxk0aBAVFRWF7orBYCgQJScANm7cSN++\nfdl///0RQhS6OyWJlJLNmzezceNGhg4dWujuGAw9mlQKFiyAtWvhwAOhthbi8UL3SqGtAhJCPCCE\n+FQI8abtvT2EEM8IId5NP+7u8t2ThRBrhBDvCSGuyaXDzc3N7LnnnmbwzwEhBHvuuadZRRkMEbNi\nBey7L0yZAjNnqseBA9X7xUAQG8CDwMkZ710DPCelHAY8l37dBSFEGfAr4BTgS8C5QogvZdXbzjZz\n+boBcw0NhqhJpeDEE+GLL6ChAaRUj198od4vhvmXtgpISrlUCLF/xttnAMemnz8EvAD8Z8Y+hwPv\nSSnXAQghHk5/75+Be2swGAxFSqaqp7UV2tqc921rg8cegwkT8tvHTHK1Aewjpfwo/fxjYB+HffYD\nNthebwSOyPG4BWP9+vWceuqpvPnmm/47h8ANN9xAM
 plk2rRpeTmewWAIzooValbf1gaNjVBdrZ63\ntDjv39gI69blt49OhGYEllJKIUTOFeaFEJOByQBDhgzJuV+9jba2NsrLS862bzCULHZVj0VDg/d3\nqqvhgAOi7ZcOucYBfCKEGAiQfvzUYZ8PgcG214PS7zkipfyNlHKUlHLUXntppbPIO21tbfzgBz/g\nkEMOYfz48TQ1NfHcc8/x9a9/nZEjRzJp0iRa0qJ///335/PPPwdg5cqVHHvssYCa2U+aNIljjz2W\nAw44gDvvvHNX+zfeeCPDhw/nqKOOYs2aNbve/+1vf8vo0aM59NBD+fd//3eampoAuOCCC7j00ks5\n4ogj+OlPf8qwYcP47LPPAOjo6OCggw7a9dpgMITLggXuqh43ysuVN1ChyXWquBA4H7g5/fgXh31W\nAMOEEENRA/85QCiar6lTp/Laa6+F0dQuvva1r3HHHXd47rNmzRruv/9+jjzySCZNmsTtt9/OnDlz\neO655xg+fDgTJ07knnvuYerUqZ7trF69miVLlrBjxw5GjBjBZZddxuuvv87DDz/Ma6+9RltbG4cd\ndhjf+MY3AKitreWSSy4B4Prrr+f+++/nyiuvBJR77Msvv0xZWRn9+vWjvr6eqVOn8uyzz3LooYdS\nrMLUYCh11q5VKh034nE14FuqofJy+Otfi8MVNIgb6O+BV4ARQoiNQoiLUAP/94QQ7wLfTb9GCLGv\nEGIRgJSyDbgCeBp4G/iDlPKtcE8jvwwePJgjjzwSgB/+8Ic899xzDB06lOHDhwNw/vnns3TpUt92\nxo4dS2VlJf3792fvvffmk08+YdmyZYwbN45EIsFuu+3G6aefvmv/N998k6OPPpqRI0dSX1/PW291\nXsazzjqLsrIyACZNmsTcuXMBeOCBB7jwwgtDO3eDwdCVAw9UA7sTySTccw/MmQOzZqnHjz6C0aPz\n20c3gngBnevy0QkO+24Cxthe
 LwIWBe6dD34z9ajIdKGsqalh8+bNjvuWl5fT0dEB0M3vvrKyctfz\nsrIy2nzWkRdccAF//vOfOfTQQ3nwwQd54YUXdn1WbbsDBw8ezD777MPzzz/P8uXLqa+v1zovg8EQ\nnNpa+NGPnD9Lz8lYvRo2b4adO5X3T7EEg5lcQFnwr3/9i1deeQWA+fPnM2rUKNavX897770HwLx5\n8/jOd74DKBvAq6++CsCjjz7q2/YxxxzDn//8Z1KpFDt27ODxxx/f9dmOHTsYOHAgO3fu9B3UL774\nYn74wx92WRkYDIbwiceVSqemRs34hVCPySR0dMDll8Ps2fDrX6tVwCWXFE8wmBEAWTBixAh+9atf\nccghh7B161Z+8pOfUFdXx1lnncXIkSPp06cPl156KQAzZ87kxz/+MaNGjdIaiA877DC+//3vc+ih\nh3LKKacw2rZWnD17NkcccQRHHnkkBx98sGc7p59+Og0NDUb9YzDkgdGjYdOmTlXPXXcpXf+OHcpL\nyE5TU/EEgwkpc/bcjIxRo0bJzIIwb7/9NoccckiBelQ6rFy5kp/85CcsW7bMdR9zLQ2GaJg/X6V9\n8HIHTSaVwAg7GEwI8aqUcpTOvsZhvAdy8803c8899xjdv8FQIPw8g6A4gsGMAOiBXHPNNVxzTU45\n9wwlQDFnmeztWJ5BXiuAYggGK0kBIKU0ycxypJhVfwZ/nFIP/OhHyhhZLC6GvRkvzyCLYggGKzkj\ncDweZ/PmzWYAywGrHkDcTBdLklLIMtnbsXsGVVV1/SyRUO8XQzBYya0ABg0axMaNG01qgxyxKoIZ\nSg+v1APFkmXS0OkZtGABrFkDn38Oe+0Fw4cXj7qu5ARARUWFqWJl6NV4GRiLwbBo6KSqqriFccmp\ngAyG3o5X6oFiMCwaSgcjAAyGEqO2VhkQnSgGw2KpkEopf/3Zs9Vjb7SdlJwKyGDo7VgGxkwvoGLK\nMlnsGC8
 qhREABkMJYjcwrlun1D7FYlgsdrwKuJx4osrW2VuuoxEABkOJUuwGxmLFeFF1YgSAwWAo\nadwiot3eD8OLqqdEYRsBYDAYShY3Xf4dd8DUqd3fX7gQPv4YKiqgtbV7ezpeVD3JflBy2UANBkPv\nwmuGv+++XXX5FkKoCGmn9xMJ9xVATY1aASxe7Dy79zpmTU1x2A9MNlCDwdAj8Jptv/uuuy7fbV4r\npfPgX12tVgV33KFWAG6z+wULnFcOoN4vNfuBiQMwGAxFiV/Oo9Wr/VMu6xCLwfnnq5n/1KneOZZW\nr1YFXZxoaoJ33sm9P/kkZwEghBghhHjNtm0XQkzN2OdYIcQ22z4zcj2uwWDo2fh562ze7B4RHYSd\nO1WJxsWL/b2DXEp/76LUUpTlrAKSUq4BvgYghCgDPgQWOOy6TEp5aq7HMxgMvQM/b5299nKPiHaz\nAThhGX51vIP23NO7rf799Y5ZLIStAjoBWCul/CDkdg0GQw8nMzXD4MHeOY+GD3cuxl5TA3V1Xd+v\nrlaPTljpM3RyLB1wgFIZOVFVBSNGBD/vQhK2Efgc4Pcun31bCPE6aoUwTUr5ltNOQojJwGSAIUOG\nhNw9g8HgRdT+7W7tOxl73Wb30Dlox+PuEdFnn931/SFD4LTT3NNneBVxKS9X3z/1VHcjcGVl6eVh\nCs0NVAgRAzYBX5ZSfpLx2W5Ah5SyQQgxBvillHKYX5vGDdRgyB9ug3BY/u1u7S9cCKef7uxamUh0\nN7oKoWb4558fvA+WAHJLn5FNH6GzwEsxxAEEcQMNUwCcAfxISnmixr7rgVFSys+99jMCwGDID7r+\n7dmuELzaj8WUvn7nTv3+Rulz7yQkHnsMpkxxrvFbWQn33gsXXBB+X7KhUHEA5+Ki/hFCDAA+kVJK\nIcThKNuDjz3dYDDkC538OMOGZR8B69W+m0rFiyhz9jjlWPIyELe2wsaN4fcjH4QiAIQQ
 1cD3gCm2\n9y4FkFLeC4wHLhNCtAEp4BxZzCHIBkMvw88DZs0aNdhnm0HTq/1ssLxy8pWTxzIQO60ASrkITygC\nQErZCOyZ8d69tud3A3eHcSyDwRA+fgPc55/nlkHTq/1sqK5WaqN99w0/J4+TUPEzEDsZf0shYZxJ\nBWEwGHwHuD33zC2Dplf7TsRiygDc1uYsNMrL4bbbYNu2zvfCyOlvNwI3NCj9/kUXwbXXwuOPe3sR\nubWTKZy+8pXiEQxGABgMBt8qY+++m5sKxKl9NyVwLAYXX6wG+DfecO7TVVfBLbc4fz9b+4BToZiW\nFvU4Y4YyPC9cCBs2eBfh8So4c/zxqv+WgInF4JJL4Omn4aijgvU3DIwAMBgMgHeVsZEjg6tAvNp/\n5x249VbnvDqJhBr843H3Pt16a+45/TPxMlSDGtBPP915dWFX93z8sbtHU6YAbW1V2zHHwNKl+RcC\nRgAYDIZduFUZC6sOsb39sWP12nPqUxRGWR1DtdPqIlPd41ZrwAsp4aSTVK6hfKqDjAAwGAxahF2H\nOJf2sjHK+qFjqM5cXTipe7JxawW1ash3OmkjAAyGiCgFLxBdMs9l2rTszsXpmmQz4IW1IrGjY6i2\nVhfWeSxYoJ6Hwc6dSg2UTwFgKoIZDBEQdVqFMPETVGGdSxTXxC+1Q1BWrIDvfa+rd5Gdmpqu3kB+\nbq2xmBrYq6uhrEwZlZub3fdPJHJXAxUkFUQUGAFgKEVKoWyghd+gHNa5FPs1sQvBwYOVQLn1VvVZ\nS4t+TiA7ySRMnKhqDVjCaeVKOPpo7+/MmZPbKsCUhDQYCohOWoViKBvo5a5o+dJney6Zq4rWVr12\nCqE28xKCmS6fjz3m7Slkx4pVsPf/qKNUXMH99zt/J1sPpmwxAsBgCBmdwiLFgM7gns25OA2obW2d\nPvVu7XgFT0WlNvMSgk4un6tX+6t9kkl3W0QqpYLLYjFnY3G+00q
 YmsAGQ8joFBYpBnQG96Dn4lbH\nt7nZPfCruhoGDfKu/+ulN88FHSFosWKFmtG7EY/D+PFKhfPRR92F1ooVSg12//3unkJ9+rSzZs3/\ncNFFFwU7kSwxAsBgCJnaWvdiJtm6KEaBzuAe9Fz8gqnc2gH9gThMdFc4lmBzKwgP0NGhagK/9FKn\nwLKqnM2YoYK9vvjCaSUkicVaKS/fwfbt32TWrGtZv349rdn6kwbACACDIWQsF0WnUoXZuihGgc7g\n7ncuUnYt47hmjXcwVTzu3M6GDd4D8Tvv5H6+TuiucHQEW2srvPgi/PrXsMceMHOmmvFPmaKuj9cq\nprX1fg444ChuuqmWDz74gOeee46YW+3JEDFeQAZDRITtohgFuq6ZTufilKeno0Pt7zRTTibhrruU\n/jvzmsyf715wBZR75AsvhG8LaG5WXjp+3kmzZ6sBPZrhUnL88Vt49tk9EG6FiwNgvIAMhjzh5bXi\nllahmNCNxs08Fy/jqdsY1tEBZ56pBtZM/IKwmpq8s3w6/Q5S+nsUSakSy910k3ptd/m0VmuplMrv\nk02KB1322GNP1+sWKVLKot2+8Y1vSIOhWFm+XMqaGimTSSmFUI81Ner9nk59vTpfNYR23aqqpEwk\n1KP9/UTC+/osX672cWoT1PHq652/l/k79O2rHr1+G/v3QMrKSinjcSlnzZIyleq6T3W1e7/ctw7t\n/eqmrw3ttwFWSs0x1tgADIYscPN2idprpVjwMp6mUmo2nzmjbWpyvj6WofSpp1RCNDec3E7dfocd\nO9Sj22+T+T3ojNK9/fbOtr/3PbWP07kmk0qdlStJtnPOnd8uyE1jVEAGQxaUSrBXVPglTvvlL1Xq\nAyfs1yfTBlFZ6X7MTLfTVErlJPLyzHE7tvXca5+1a91TQsRiKsp3+nQYOFACQfQ3ylBSSTNxmnmG\nk4i3NxbkpjECwGBwwUu/XyrBXlHhp7P30p
 Xb6/lm2hG8JsF2t1NLcDQ1BdPLW8eW0r8GslvBGYDW\nVsn777/MmDFXAiOBOuxCQAjB9DPf4M4Fg2mjjEaqqaaRctq5itsQwAGso5bHiNMCjaIgN01YReHX\nAzuAdqBNZlighTJt/xIYAzQBF0gp/xHGsQ2GKPCLSu2pRcJ1sdxDjz022AwcOq9PkJiBZLKrUTZT\ncAQ9tvXcqwayF31IsXjxrxg9upw77xzFSSdt5pe/3Is1a2DECLjxRqi56y9cs+AmFjCOdRzQdcDP\npKJCRcPlG11jgdcGrAf6e3w+BliMEpHfBP6u064xAhsKQVOTMvw5GexqapSBMJXy3ydffa2vV4bL\n+vqux/X6LCymTw9uHLWuz6xZykAb5DtSehugddvx+/2mT5dSCHcjbpxGuerFv3tfnPp6KSsq9DvX\nr18oHgQUoRH4DGBuun//C9QIIQbm6dgGQyB09PvFEOxlpRaYMkX5qE+ZonzaV6zw/ixMDj5YnbcT\niYTarOtjFXp//HF1fbyCsDKx6+51Knc5EYt1Htvv99ttt03EhdvSpoNruYmvPvKQ9wFra90NIU5s\n26aWVDNnKqt4PozCupLCawPeB14DXgUmO3z+BHCU7fVzwCiXtiYDK4GVQ4YMyVkaGgxB8ZqZCiHl\n7Nmd+1qz7Nmzo5tlO+G3SunXLz+rE7+Z9DPPKNfOWEy9V13d6Y7p9V2n6z5jhrrG48crl82gs/+K\niu6uoPbf7957t8tf/OIeecQRR0iolEk2O58XW2SKSilPOMH/As2ald1SJQefYgKsAMISAPulH/cG\nVgHHZHyuLQDsm1EBGQqBl4rBzRc9W7JV03j1MR53HyCD9l+nf27xEEuX+qvJMn3x3baqKiVELEGS\ny1aTaJGp6TdKWV8vm7/4Qj766KPyzDPPlBUVFRKQh48cKZ+YMEG+NHyCrGGzTLJNCtpkkm2yhs1y\nOaNUQ+PH+1/AVMpdG
 mt1NrjEzrsA6NIg3ABMy3hvDnCu7fUaYKBfW0YAGApBvvT7uQSSBdGfZ86k\n7SsYJ6xBf8oUNXvX6Z/TSkhXkFrfnTHDOxDMb8Lcr58KAPPdl+3yd0yQqYoKuVUIOQrkgAED5LRp\n0+Q79fVdJFITcVnPuXI218l6zlUzf6uhfv30bgZdKRfSjCOvAgCoBvranr8MnJyxz1i6GoGX67Rt\nBIChUEQd5atjaPYiqhWATuRrIiHl1q3+5+gnpGbMcD++/bp7jY/xuJqIW0LH+r7XSkHQJmdz3a43\nWpNJuXPHDu8fJdfB2S5VM0Okc5XYGQQRAGEYgfcB/iaEWAUsB56UUj4lhLhUCHFpep9FwDrgPeC3\nwOUhHNdgiAwrR86cOTBrlnuO92x55BH3YuI66Y+9MnlaRk4nvNJR290rvYysTU2w337+BmU/I+/P\nf969jczrPnGi8pB0o6VFciirmLB2NvHH5jN6ZDObNsHFF7tH6VbTyAF0+txXAOULFwbPZR0k4MNK\npnTvvaro76xZ6kfyinyD6H2KdSVFITazAjD0RJYvVzNXr4mfzqTPa5WSzQomqHul30pFx8jrt5rw\ns6HGaJb1lRd2OcmdL78sH330SVlRscO532zuqsqxZtlBDba5GoSamqS8/HJvV9FEIlIbgIkENhhC\nQLeWrTXL9vPwk9L/mH6ZPHWyfNoJ6l7pl/JCJ1jMWk24pXoePNi9fCJAOTupbZkPyF1RXQ1HHskE\nKUn0+y7NzX+hrKySVKoP1bKBcnbyV07qGoxlzbLXrtU99fTBc6zuU1UFe+4JO3e673PeedH6FOtK\nikJsZgVgKAWCzLZ1Z9n5DCYL2jc/PX4mOsFiTudrXVd3XX67XMa3u33QVF4uX736atna2tppnJ7Z\nKusTF3ed+dsPvmVLMP1/GAYhv/Sn1dVZrTAowkAwg6FosbJRWlWtgsTfBM0KqjvLjrIMohtB45bA\n
 WY+fiVewmEUqBQ8/3PW1e7oHSRUNvMDRHMXL3T6tam/nsJoaKioqdqner7+hggkvTCZeU+Uc+bV4\nsb7+v7JSRZTlYhDSqTFZURF5/VAjAAy9mlwjZoMUFQf96NdCJJSLx+Hqq4N9xyrU4iU0vQzWFi0t\ncNllndfd67rGaebX/IijHQZ/wN1w6mXZD6L/ammB007LLVLXz+CcSOQlpNwIAEOvJYyc/kGKis+f\nD6tXd5ZN9MJtDEul4MEH4ayz1Pbgg+FnDAhamcpvtWLZAhIJ73aamzuvu9d1bSHGRga7N1RW5j5z\n3rUkuF49WgNskLwUkPsSzU/gTJsWfv1LB4wAMPRags7endApKm5fZfzf/6sEjRBqLHLDyb64YgXs\nsw9ceCH86U9qu/BC2Guv8HL8BB0HQW+1Mno0bNzoLwTa2uCBB75gzZpFCOE8QFpunK5yqqNDFSwO\ngs4yxU6uSzSvC51MqpSiecAIAEOvJYyc/l7jRnk5nHJK91VGKtUpBC6+uGvCNLeEctZqZceO7sdp\naFCVq8JYCWRjB9B1Vd99d+Xt46XVaGjo4IorbqO+vhYh2h33KaeNWjyk844dwcuyxeOwcKH6MawA\ngiDVaYLideO0tSm3pzwkgzMCwNBr0Zm9++GXVdLLttinDxx3HGzYoAKejjtOPb7/fvfV/4IF3uNB\nc3M4RuM33gieabOjA8aM0dt39Gi45x53ISBEE6efPpLVq1fxyiu7UVMjSbIDQTtJtlPDlu5unE60\ntSmDhpdl3279nz1b6fX79FGDbyymJKHbDZKrC2jmjWOnpQWuvDKa9K2Z6LoLFWIzbqCGKAkz549b\nVlC/zKJTpui5kOrEKAXMGOB4DjqekH36dH1dVRXMK/K111bLysoml+ve0b2mwfjHnHPx+G2xmF5F\neK98FX37qpw/QXOC6Gb5a2qSsq7OPTIw4mRwJhDM0GuxJmGZlb/Ky4M7YFi2x
 Uy8KoclEjBvXldP\nQGu/E09UDip2G2U87r4KqKzMPWOAbiaETCNxKtWporL3edeHCxbQ+MYbvPTRR8x6801eevVV+vQ5\ngvLyZygvj9PSUk51tUhfd9Hl+1VVMGHeKfDMhe4Fet2woscyL6qU+iXFpIQ77lArAqeIOqcIwDfe\n8C4nZ6eqSrXtpQ6KsFawEQCGXo3lGfjII/Dkk+q9sWNh5Mhw2veqnWtN85xobe36v7facRMA8XhX\njYRuZLIdXU/Iykpn9/XMsar1pZfgpJNob26mqr2dbwGLysp4YupUjv/P/6Rfv756kcrxODzzTNdB\ntaIiWDFgewet5zo0Nirr9fXXd//MrW5oW1tXie8m1S0KWWBad6lQiM2ogAz5IOrMn27tX3SRtwZj\n5szu7TilO04mvbUbuuejEwk8bpy3SmvWrA750ksvySsuukhuddsx2zBnu57t8su9U5a6ddDK+aOb\nS9st30/QzKFebYVcgIJC1gMIczMCoPjIR53ZfJJrWuYgx8m0EUye7D1eTJ7s3E5dnUqBPH68ep6p\nM8/2fLxsIrGYlB995D1WxWLNcu+9p0pAXhCLyaby8tAGtUCd9RuAg+S8cLto9fXBixe4pXYOuQCF\nEQCGSIh6phwFfgIrn9W/Mvt08MHe48W4ccHb9jqfykolMLzw+429x90t8thjT5YPPfSQbL7uOv26\nmk4XR2eGkVm8IBZTFmm3C2ANplu2+A/efje3ToKjIDdUiH+uIALA2AAMWjjlZvFTbeazb076bjcV\nrd0Wl2/1q71PToZhO0H98cEngrYFJk+Ggw6Co45y3scvw2hZ2U6mT3+Fa645jJ07JZBAiGbi8TL+\n8IdWTj11sdpx/nx367ebj63OD5bZ2YUL4eSTO1OG2n1xobtl3zLQStm1Lcv//6qr1PftJ+50g23e\n7HwBvfByHfW78FGhKykKsZkVQPFQiJmyDrnUo7XOy20y
 mEiEd15NTVLOmeOd+j1z85utO6Gr3Vi2\nTL/Njo4OuXz5cnnllVfK/v37S0D27z9YnnTSQ/LSSzfK3/2uo/tEPahaIxvdld936uq66ty89ncr\nTJCtAaeysmBLZYwKyBA2fv7sufqgZ4Pf/1lHYG3Z4n1eOqUP/Vi+PHia5WQyO/uDrmq8stK//Q8+\n+EDedNNN8uCDD5aArKyslGeffbZ84oknZGtrq96JB8mT7WbUDct4GnR/vxvMrbRjVZUSPk6BIXkg\niAAwKiCDFl7+7FFXrXPDL5ePm5egXbWzeHHnKj+TeBwWLcrNBTuVUmka/NQ9FhUVShvxzDPZrf6t\n2IZjjvGOHG5pUemXL7ig6/vbt2/n0UcfZd68ebzwwgtIKTn66KO5+uqrGT9+PDU1NfqdCaLWWLo0\nuC4uqP4u6P5eN5hXxrxYDM45p3A60QDknApCCDFYCLFECPFPIcRbQogfO+xzrBBimxDitfQ2I9fj\nGvKLX86biNOWO7J2rfvAakXzO2EXWGvXug+Uzc252wD8UjhkUlEB69fnnghSJ6OnFffQ1tbGU089\nxQ9+8AMGDBjApEmT2LBhA//93//NunXrWLp0KRdffHGwwd/CLfumnVRKRcS5kUg4zzCC5vIIur+X\nwGhqUtW6nAodZJOMrlDoLhXcNmAgcFj6eV/gHeBLGfscCzwRtG2jAiouis0LqK7OW83hptvPtAGE\nYdtwc14pRJlZPe/IDvnd726VV199tRwwYIAE5O677y4vu+wy+corr8iOjo7sOxEUP8NFPO6sQglq\nZwi6v9/NUVeXHx/igJBPFZCU8iPgo/TzHUKIt4H9gH/m2rahuCiUo0K2XH013HVXV6eSsjLl6HHr\nrWpCOGZM7iubZcuUI4qldkomO51XgpKr55FuOgeQvPfsj3nxxd8zduxYJk6cyJgxY6j0yoAZFX4h\nyG4FFOy5PJqb1RaPd76feWNa71u
 pU1taVFiz2/61tXD55c7Htm4av3ziEaVwCItQbQBCiP2BrwN/\nd/j420KI14EPgWlSyrfCPLbBnWzSArjhlPMmzPaDsGGDUnWoRWZXhFAqILvAkhJuvx1uuaWrd+Ad\nd8DUqdnlA1q2DL7zna59sNRSxxwT/JxytafopnPoSwP/L76Q9vfeZ8/99vPeOeof+MAD1UDspisT\nwnswtebdmc/dEKJTR2Z/nskbbzgLn2RS3RxPPVW4FA5hobtU8NuAJPAqUOvw2W5AMv18DPCuRzuT\ngZXAyiFDhkS1Suo1OMXKJBLd3QC94m+cPrPemzJFtVddnX+1UBD1jZ/H4JYtwZ02mpqCB4P6bblq\nDry1KR3Dm0beAAAgAElEQVSyghZZwxa5nFF6+iYvP9tsQsKdbqZUyj0bprU5uZkFdR318+qZPl3P\nZdRqu0h9o8m3GyhQATwNXKW5/3qgv99+xgaQG173sBCdQsBLt+/0Wd++6tFLbZsPFWgQlW7Y/9Wm\nJpWOpqws+8Fe11VcOzi2qUm+d+NtMlm23fF4cRplHRM7Uyr7+e/63UBBjUFeN5qXscTtB6qrUxdR\n9zs6QRJWn2bN8r9hQk7hEBZ5FQCAAOYCd3jsMwAQ6eeHA/+yXnttRgDkhpdrtTXp2bLF/R7u1y94\nupUgg2oYeYV0DdNhxjFYx4zFsh/8LRui36pD5/w+/fRT+furrpLbysrkdpD/yyhZwxaZZLsUtMsk\n22UNm9Wsv4tEiHtHmwXJmeM36PnNqLduVTecbrvLl3uvGpx+1CBJ4OJxvRum2DwjZDABEIYN4Ejg\nPOANIcRr6feuBYakVUz3AuOBy4QQbUAKOCfdUUOE+OmD29qUd56bHau5OXiBcAs/FWjQqH83dA3T\nYcUxOKXEyIbycn9Xce/0G5K7736MRx55iCWLFvFBezu7pfc5gpVsYl8WMI515SM4QLxP7c6Hu1fR\nam5Wxo8vf9
 n5ousaFCy8DJ9+QRuLFnVP+exmjLEujJd/rZcbqE5QhpTudgl722F5RhTKkKYrKQqx\nmRVAbtTXe89ShZDy+OP1J0VhrQDylYHTTlir9aCT4szrHWSC6H2s7RLOlfvtt5+cf+qpsi0XY4RX\nxssgJ+u1lNJdgrmVVrMvF3VSQQd1A3VbBeTjJg15FUGAFYCpCZxn7GVI3UqVhoVX8BaoiczBB7vH\nxlgectng5ULpNxkMo7ZtJk61ey2Pwauu0m8n6KTYIpGAGTNgzhyVOG/XhNvthkilWLvgdRob3BbK\n1VxxzIX865JLODcep8wplFkXt4vudwN165LHUsorCMse6GW5mV19tXp9001w1lmwxx4waZK6iPfd\n5/0j+LmB2m8CNyor4T/+w73Yc1izc/syr6FBiZiGBvU6aGH7bNCVFIXYSnUF4KbbLoS6cNky94mX\npXoN0wZQXe1/ToXMK9TUpI4fj3faD8OalcdiKke/dglZtxviwQdle79+8qHyiTKJs0E3yXZZX3mh\n+p6bITSMmXsQg4fXzNhr9m33SLAf0y3Xjt+s3S+LnvUHnTnT243L7u0UVU6fCDyJMMngCkeu2Smj\nYOlSdZ+71cjW8QLyG2NiMeUSqvMfKaT3XK7qJx1V0ubNSktx/PHq0TGhnEdHOtKPKSplDZudj8Xm\nYAXSvTa/i265PHkJgUTCX4IuXeou+a2B28srQWcL+mdavtzd+JyPP2cEsyEjAAqEn5tx0GSHYffN\nayLjpXqtq5PyS19y/48I0b18oReF9J4LQ/gEdZt1XAF4dKTD9nw5o2QNm2WSbVLQJpMVqU4/fqeT\nCJJvOizJ55ZKOcjFt4RAIhEsuMJtVhOEujp3fX/Uf84CrwBMNtAQCSM7ZVQ4RfD6fa5bvKS6Gvbf\nX6mwdZwY7BH82UTf5kIYBWDcHD+khH331Sua88Wrr9KvoQE/J6vRrGQT+ymPHg7kgEGS2vd
 /3t2j\nx0JK/xOorFQ3Y5CL7vej6SSK8zOgBNV3J5MwcSIMHJhbXpING1RaCCei/nPW1ir3NyfykGXRCIAQ\n8bq/d+7sLFqUSaHSKXsRxN1RCOVN2N6u79JZqLxCYbmDOgnM+fO9JwD19U0I8TDz5s1j4AsvMAeV\nPTGTTKFQRTMT+L3q4Ic7AZeZhHUgP047DQ49NPhFt360Rx7pTCU6diyMHKn3/SBumDqUl8Ntt+V+\n0xQy13khZ0NgVEBh4reac1vZ9utXfMXV/Vbr9lW3XwlWP/JZaD5s9ZNd33/44V7ainZZWTZTAnLY\nsGHyphkzZNtuuwVT1VRV+bs/+m25qjRy8WTIppC727bbbuF5T+jcFFHfpH462gBgbACFwe8+WrbM\nebDs27f4Cqv7BU2ecIK6T+vqvAsjZZtqJqrrkasXkJ0HH9SPoUiyTT7Y54fyzXvv7Uy1nHnyfvlw\nwgjayMXIEkYAh45XQVWVt8E5FsuuXqZOv3Iy7BQHQQSAUQGFiN9q7itfcXar3rGj+AqrDx7svSoe\nMULt+//+n3M1LavNNWu8j5nPQvN2m4Y9E/BPf6pcvt1qlTgFaG7ZAhdeqEYkHcpp4/sdfyR+Wb2K\nvD3qqO56sFWr4E9/cm5ACOULn60KJZnMXa3gZeTauRN+/GN1YUCphpxCne1qpMsuc9b7V1aqz/7n\nf9yPtXFjdufgRhiGnVJEV1IUYiu1FYCF22quSJMHuk5w3PpqzwPm53Ry+eXux83n9Qgyec3MdOo0\n8bv8cq/z7pDltCivHbZ1z8OTSASPvK2slHLcOHc9otvKIJGQcsaMcNQWQXLp6CxtvWbWxfJnKZZ+\nBACzAigsbh43YXighI3XLLxvX+jXr9O4m0ioSnhSdu6zc6d3+3vt1fVY9tn0mjX5ux460ccTJnSu\nEnbu7N43ex6ef/u3rcDudDfZKkawhnN4hANYRy2PdfXaaWlR5QTHje
 tqhPXyCGlpgT//Wd1cVhhz\nc7NeUYNc60taBDXi+i1tvTwBRo4sqHfMLorxTxsiRgDkkWItrO7mntreDnfeqbyX1q1T/+O6OneV\nTyaJBAwfrp5bA6u9cFOfPmo8a2rq/l3d66GbQ0vnf6zr+bRtWyOrVq0Evue6z3fE37he3uj8YXu7\nUvU88QRcdBFce22nDsquQ8y8UaTsvFhCwPTpShdnnfTZZ0frVuUloNxobvYu5uI2Wyq0d4xFMf5p\nw0R3qVCIrVRVQG4UY/rw6dO9V/H2AC+/fd3OqalJaQPCtlUGsc3pxPro5z5rl2ee+aYUosNFG9Mh\nt8YHBDvhfv06O27poI4/3n3/QqkfMi+6ToqIXHJ7hOgdkxXF+Kf1AaMCKk6cJniVlWoyFyQhmRPZ\nZpPdvNn7888+62z/lVe8962oUOeVOVF78EGlDXAjkVCrgSCTvCAG5BUrlH3SLc7I0ijceqteordk\nsg9nnfVlzjyzuyFYCKirE9Qc+EdVE9L+oRfbtnV2vKpKqYcuush9/0KpHzLVNh99BPff7x5IFY/n\nNkv2i2AMG6c/UjGsRKJCV1IUYutpKwALuyuiVXciF8+yXLzU/Gb1M2Z0tu9n8B03znmiNn68//eC\nTvJ0bXNNTf6Vy5Yvl7K9vV1On/62LC9P+a9O4k0yVfd7KVOpXXEAJ5zgkPfHnoRJZxVg73h9vber\nZDzunW87n4EVhcylEyZef6R8rERC+t0wcQDFTZj58HNtq77e24+/rk4/dsfNNfvMM72/N368/vla\n6ObQqqvzPvbs2R/J6dOny6FDh0qolLDFZd+OdGWtLXI5o/WlrPWnHj/e38/f3nGvEomWAMi2hFjY\nLF/uLGVjMXUepSAAClGkwk6Iv1sQAWDqARSAMPPh67TlVYOgtlapoZyw3tfJLuDGihXw9NPe+4wd\n6/25U/+90svbbXNWxgJnJNOnL+XGG29k2LBhz
 Jt3Hy++GKembxtJdiBop5rtJGhgCnOYwxQ+YiCj\nWaGXs92uThg71l9dYO/4gQcq3303rr22e3uFyi0/ejR8+qnyEDj+eKULtPIN3XKLytWzYkU0xw6L\nQhSpsChkTQBdSVGIraeuAMLMAOvX1pQp/hMLv1rduq7fmf32mlTZtR5ekyu3vi1bpjdh81Y/dciR\nI9+WGzdu7NLppn4DZD3nytlcJ+s51zvtspsx1qnjyaR3Kgd7x72Mj265Q3T0YlGqhwo9i86FQhap\nCDnWAGMELm7C9CzzaiuRgHnzurpZWvsdc4xy8ayoUMkQf/EL9f7GjV09CN99V8/1O5ns3m+vSRUo\n+97zz7tPjL0MvaeeCuPHK/ujHSGUS3w8riY3Bx+8DjgAN3/9q646mP3269rpqvYGlXxNBydjrFfH\noXtWwKoqNWO2GxWzcYP083VdulS5ceZaiNkN3WCLYqSQ7p6FjDXQlRReG3AysAZ4D7jG4XMB3Jn+\n/HXgMJ12e+oKIIhnmd+EzS9Nu25JV2tmPWtW12OlUnpt9OunannU1alZ9/jxyrjr9Z0ZM7yvU7b1\nd3fbrU3OmHGTHD58uDyMSplkm+N+ffs6TEqDRrs6zdCCdtwrn34Q46NfJLGbsSes2XkhZ9G5UupF\nKmyQTyMwUAasRU2zYsAq4EsZ+4wBFqcFwTeBv+u0HYYAyKdDRBC8KodZ/Z01S88u5NbWlCnZ5w6z\n90fHhz9oHQ+d+zroWNy5bZPf4lz54L/9m2yNxdJFVbbIOE0S2mWcJlnDVrn8ue3dDxp08HYaHIJ2\nvLJSScxcb9Bss22GFVMQdtqEfP95C5X0LWThk28B8C3gadvr/wL+K2OfOcC5ttdrgIF+becqAIo9\niV/m5M7Sa/uNP073hNNEMdsZdObAnmsb2d7X2fZf0CZnVfx3lzebiHfX6zuVMdQdRCsru7sIWgNV\nXV12HQ/jBvUrceh4wXKY
 ndvPva7O/djZlGosxJ+3UIFnmS7DOsW1Xci3ABgP3Gd7fR5wd8Y+TwBH\n2V4/B4zyazsXAVBoe1TQyYuOwTToZCqM9Ou6LuxBxxt7DfCw+59km6znXL2dnW6G5cv9XTbHj1ff\nC5pJL9s+BcEr7DmXGyoTp3Pv27fT4J3twF3oP2++sV9H60+XSOj9SRwIIgCKzg1UCDFZCLFSCLHy\nMysMNQsK6dW1YoXKIDtlCsycqR79POH8DKZ2dO1Clh2xpib7gMXWVmWzDJPqavjXv/z3s/e/uroD\n6ACa04/ulNNGLZo/sNPNMHq0ys3jRiwGe+/t7b7X2qqMu9XVyjJtPWbbpyB4lTh0Ipvkam7nvmOH\nau+uu2DWLJgzR0ULBzEyF/LPm28yryOoe6epSVVui9IFlHCSwX0IDLa9HpR+L+g+AEgpfwP8BmDU\nqFEy204FNaxnm0ohE78UBevWweLF3Y/jVy7VThCnBJ30637HktI9YVw26AqwhoYGVq9ewNe//jBL\nltQAQznwwDibNv0HqZRT8IKkhi/4Kye518zV6UwqpVyk3GhthYceUjkuvPax8nwcd5zK5X/IIWpg\n9CuynKvnh1/WzmxqAmfiN0jHYnD99cHatOjhGTi7UGDPqTAEwApgmBBiKGpQPwfI7PFC4AohxMPA\nEcA2KeVHIRzblSBeXfZCIbl6xy1Y4J4iubUVBg3qmvfGOk6QTLvl5aqt2bP1hFVVFVxwgapDYj9P\nqSFeKyrg8cfVZMRv3NLFS4C1t7ezZMkS5s6dy2OPPUZjYyNDhw5lxozzOO+88zjooIM6f6/Wdhqa\noJJWBHBtn5v5j46f6Q/+oC7CoEFd31uwQGXs9EJHWluz8OefV4/JJJSVqQo0r7+usoE6SeRc3Q69\nsnbW1Cif30x/36BEOUj39Aycdgos7HIWAFLKNiHEFcDTKI+gB6SUbwkhLk1/fi+wCOUJ9B7QBFyY\n63H
 98PoP2Fe8YVelWrrU/ffMTHtsP8777ztXC7OwaxHa2uDKK4MJq1RK+fRfeaVKANe/Pwwdqj7b\nuFGNg7fd1rWwuz2dvJX/a80a+NnPgmkYMikvh9pTUjC/c8n11ogRzP3DH/jd737Hpk2b6NevHxMm\nTGDixIkceeSRCJv6ZPRXUmz62Z9YcMVzrGNQZ879jiw7tXChmrFmsxwLgvWD3367+sGHDnUWAEFU\nMm5LV68YgjB8/qMcpHX/vD2BQgs7XWNBIbZ8eAGF6bnW1BTM9pZ5HKf+9uunDMmzZ2fvZOF3HSyD\n9fTpKqGZVwEpr+sVi6kMxuPGKRvp9Okux33wLSlramR7dbXsANnQp4/cDPKbZWXy1FNPlX/4wx9k\nyu9kvBKlZbPpVqMKY4vH1QXS9fN1Q/eHjcKjJWq/+WJ34QuLCK4jJhJY4VVwyCLMFdgjj2Rns7GO\nM2GCd3/nz3fXTLipC/1WOHb1Tq7Bpq2t8Le/qQhka6L5X/8FCx5pZd2Tb3MA6zj12C3EL/8/0NS0\nywOhuqODauClZJI+f/xjsNBgXTKjbzMJshzLleZmVRDmqac6VUJCdKqiHn9c2Rf69+9a8MWOztI1\nylTKURds0fnz9gQKXPimRwsA8P8PhLkC8048pnT/HQ4OLPbjePU3G8P2tGnOFbdA2SpOOsk5VYSb\n+svPVtHaqrZdY9CbKzj3JyfS3tJCn1SKlj9BhfNX6dPeDg8/rAZrJ2t8EFcpO8mkuvA6luy2Nli0\nSP35jjzSv+ZlLthVQpYkbmnpWnItkXDW8RVD2oWoB+l81wIoFIUUdrpLhUJs+UgFkc0KzM3H3y/v\nvVs+fd2VXhB1lbWC9vPjd/s8mVQqp8zz1PXNTyalvO1/PpBNQVU18bj7sj/b0GB79jg/1Y49KMov\nj3WfPtmHWtu36mr/MOrMm6SU0y4YIgVTDyAYQdSNXvv65Z531YlrqjV1hZVuUJmX
 cBDCfSzWEy7t\n8jtcJztyHRztJ+enm4/FVGerqrx14l65+e2S1O8HnTRJz1bglQFU58fI7JeU4addMPQYjADIAh17\nmV+A4tat3v9Jqz5uLna5XA3bmWOOztjkNBY3NSmDsdu41UfskA/1+WGwxv0GPy8JGI+rAXvLFvcL\nbLd2u8247ZJ02TLvPm3d6i1p7cmdxo93XwKWl/tfg8xZfQnWqjXkByMAIkJn0mWlYrE0H5WVXet9\nuxEkdYSfENHVlFgT5WzG4o6ODrlkySsyFmtwHoPYIlMVPlnkKis7pZjfcsQa/LL1Dsn8nnXyVobM\nzPB7v2WUtV9mGH9lpRJGmZWwtmzxvth+kthpVt9bPGUMgQgiAHq8EThMdIywEyYo46eTPcfNZTto\nIFouhm07lq3RijFobFRBom1t7vbFxkbJ/fe/wMyZk3nvvffoGzuSBI/TRhmNVFNNI+W0qWjcnR6V\n4ONxuOceFYQwaJA6YTcjbSLRaSXPxmDm5DFjnXwq1ekhFIspQ+xf/6qCJtwugj2XhW5/Fi9WP5yT\nRb6qSg3zXjj5v/cWTxlDdOhKikJspbgCcMMr/bNXPn8vn3w3giZRq67uVIv722y3SThXHnfccfKB\nBx6QjffdJ5uq++tX0LK2WbP0Lqx1IXJRaWST4nn69HCNrLql2zJz9icSZlZvCARmBRANXgGKHR0w\nZozzZ14u2yef7J4jrKlJ5dNKJvVTU1irjO9/H+bO7epR6EZTk3tWgkzi8QpWrbqZ4cOHqDdmz4am\nzfoVtEClI7AnW/OLvD3vvNxmtUEje9vaVLh0mBGafv7GxxyjUjRY4daffw577QXDh5tZvSEyjAAI\ngD1mw0rYZyGliux3GqT9XLb93NN1U1NkqpJ0s3hWVoLs6ADH5LASkCQSklisD3+96kWGP7KiU4d1\n4IGd+i2nhsvKuiY/Ki+Hq66CW2/t2obb4JhMqsExF4IkWgL
 V1732cg8GyyYdgU56g3g8HL/3sDIb\nGno+ukuFQmzFogLKNNB++KGeE4mF3+pfN+e+l5opSD2BzK2ysl1Cu3P/aJcnHNcm62e9J1P99umu\nw3r2We+T27Sp02I9a5ayiGdb4T1bgurEvHJz5KKOyYfR1hiGez0YFVB4OBlonaJ5LZqblcZi3Dg1\n8ZISPv5YZdV0mulb7ekEqVqGZqcJXvAgWUlF2U4qZIrjWm7lRf6TBvp27x+NTBr2DybcfiZsc9Bh\nnX66+wqgqgqWLFGz2lRKFUnYtq17G6edFjwnRRCcwu0TCbWEk7L7/vYZuZuRNZtZdqbR1kr98NRT\nyuic60w97MyGhh6PEQAeeP2f3LCneZkyRen3vQb48nL9dMtWbv599+3uMfT97wdTc8dp5hftlzKR\nR+joU8bgjquc+0cbtZ/NyU6HlUp15qfw04P961/RDo5OHjNDhvgLHSeXq1zyh1vthZmD3KIY0kMY\nSgvdpUIhtkKrgKJMCukUpFpXpzJpeqWMcMsGmkh4uZKrQuiCNplkm6xhs1zOqC47qcLpm2WSbV33\nqzpGuQhlo8Oy66yCpC7IpxojSGSe9SO5RRHrqquiKnlo0kMYpFEBhUZUaeHLyuCb34Q//lE5xAC8\n+Sb85CdqombPP2b56Fu201tucW7TLdEcQD++4A5+wkYGd+bOzyiaMpqVbGI/FjCOdRzQuV9lFYz9\nhZqJu3mwuC1x7MZS3ax7+VZj6CYcs2bszc3u7lK6s+yoZuqFzi1vKD10JUUhtmJeAVRVqVl3tiuE\nWKxzUus1IbQyHKRS/hO8iy5qlYlEiywra5TQJmMus33fjmXOuv3SDtgTrbnN2HVTFxRjjhtdC7vu\nLDuqmbpJD2GQZgUQGl6ee5WVnfV9FyxQevwgVbLsaZN/8Qt/A2487j3BKytLUV9/Bc3N89ljj4v5\nyldO5+xBLVz0lwuIN27W61QyCRMnqg
 r2mVGlfhWm/CJSdfOeh1GgIWw3SF0Lu+4sO6qZeoFzyxtK\nEF1JUYit0CsAKfXU0UG9DDMntV4qdmsV4DcRhy3yvPMukUuWLJHt7e3Zdcwv/7VVMmzmzOwrTG3e\nrNo4/nj1uHVr189zXQFEYT/QTa6kO8uOeqYeZSUwQ9GDSQanCJJgTacdr/+T07iTTErZt69/nrPx\n4/1VSTU1Um7Y8JmcNu0RWVa2TaqUDG2yrKxRJhItcunSAPUgrY4FyX9tGT7j8ewH1Fylqd/gGJVx\n1c8boLIy+DUx/vqGiAgiAITaPzuEELcCpwGtwFrgQillt3p9Qoj1wA6gHWiTUo7SaX/UqFFy5cqV\nWfXNycsuzJrY0KlpWL1aZQ7o10+5udsLrq9Zo9Is/POfzkbaZBLuuksZgL0qHVaUNdIuL6Wj43eM\nHHk4I0fOYNCgYzj00L7uGo7MDtpTC0jZVWVzyilKn2VXm0gJ++wDOxySuvXtC59+6lyq0En9YsUB\nOJ1kTU1X4262P96DD8JllzkbaZNJmDOnq3FVV1XU3KzUYk59t5LanXNOcBWLdXyTyM0QIkKIV3XH\n2Jxm6MCJQHn6+c+An7nstx7oH7T9bFcAUU0E7VgTOKfcXdbkOvMzr/4sXy5lvLJDQofzSoE2efS3\nnpSrVq0K1sFcqtxMn+7d+bo6/WMGVe0EVWMsX+7unmkttXJxNTUzdkOJQCFUQMA4oN7ls7wKgPp6\nd5/4zLEmGzVRLmkXrK26OmP8WL5c3l9+saykybnfbJf1l/9N7wIEkYBe+5aVeZ/E+PH6xww7u2bQ\nH8T+w2c7QzC6dUMJEEQAOGX/ypZJwGK3hQbwrBDiVSHE5BCP6cjSpe6OJA0NSi0DStOw774qYnfm\nTPU4cKB634tsa5NbxGJw/vlK63HQQVu5/+672f6tbzGhbR5VOKfvLKeN2v5L9Q6g42eus297u97x\ndI5pZdd0Ilcfd
 Z0fxB6T8Mgj/r78TlgxA9dfrx7t6ppUCubPV9lR58/XS61qMBQYXzdQIcSzwACH\nj66TUv4lvc91QBtQ79LMUVLKD4UQewPPCCFWSykdR7O0gJgMMGTIEI1T6EoqBfPmee9z883w4Yfw\n+993zeipG2+Ua4DYzp2SbdvWcN5503n88cepbWnhHCGI08JfOYkTeZo2yrsWWKkaR3zEFL0DBHGl\nzOVkxo7VP2bY2TXt+J2D5R5pVd9xsxNYfdVxNbUTRVoHgyEP+AoAKeV3vT4XQlwAnAqckF5+OLXx\nYfrxUyHEAuBwwFEASCl/A/wGlBHYr3+ZLFigomK9aG2F++93/9wvGDNoduFMpGygvn4W/fu/wJQp\nU/hpSwuJ3/wG8InI1R0kg/iZZ3sysZgyfOoec/jw6HzUvY5dWamMtKNHd0YZe83Og65GTAI2Qymj\nqyty2oCTgX8Ce3nsUw30tT1/GThZp/1sbAC6Lttem59KOhe/f5CyomKHfPTRJ2Vra6tq0M/NsE8f\nKf/937v7zGfTwUwdd7YnY6/oFeSYUejRw4gy1rEBOFGMkcuGXg15tAHcDfRFqXVeE0LcCyCE2FcI\nsSi9zz7A34QQq4DlwJNSyqdyPK4r1mQwF6TsTEbphKVRqKlRamE7iQQkkx0k2U4VDZAuqAKSBI3U\n8AUvPV9Bbe0YKioq1Jf8ZvYdHfDoo7DHHvDQQ8772HXQjz2mQpNrapT7oxDqsaam+2zbfjL2ffv1\nU66eTmRW9PJqJ/OYXnp0L7x07LrHDqIq0iWMyGWDoUDklApCSnmQy/ubgDHp5+uAQ3M5ThC80jeE\niT37wZo18OmnHezYsY7333+aA5Zfw2208SzjWMNwPqc/e/E5w3mH2uq/Ev/nTfD7Vco//+CD1WDo\nVhfSjpRw4YVwxhmdWeTA3W9+4ULYsMHfz9wtlcMbbwRT2URVpFxHx65zbF1VURBMAjZDCZNTIF
 jU\nZBsIZh8vstXTz56txmU/Xn/9debOnUt9fT0ff/wxNTU1PDRsGKetXIkIcm0rK/WTCV1+OfzqV+p5\nkACrbHALVspX2cEwz88roCvbaxVFmwZDDuQtECzqLZdUEJaq+fjjg6u3/VS3mzZtkj//+c/lV7/6\nVQnI8vJyecYZZ8hHH31UNjc3R1tIAKQ89tjO4IXLL8+/DjqfQVFh69ij6LsJEjMUEZhcQJ1kY+N0\nsgM2NjbK+vp6edJJJ8k+ffpIQB5++OHy7rvvlp999lnuBw2yxWKdg41foqGwi4DkI8zajp9Vf8qU\n7M4hbEO0CRIzFAlGAGRgn6CByt0Vj6uxw6lGuTVxa29vl88//7y84IILZDKZlIAcMmSIvO666+Tq\n1av1D2o1Xl4enVDI1wog314vfqupRMIMtgaDjSACoFfUA/CyD/7iF93ff//9t7n22nn87ne/Y8OG\nDfTt25ezzz6biRMncvTRR9PHL9DA7aAvvghpf39HYjG1NTYqm0Cu0aS5Blg5kW+vl9pauOQS98+F\nKL1at/mynxgMPvQKAQDulf+s9z/77DMefvhhjj56LitXrqSsrIwTTzyRW265hdNPP51EIpH7QceM\ngfAWm8QAAA+VSURBVN/+Vs1dMxEC1q+HJUs6i6JPnarSi+oSi6l6klEWAcmH10vmAHnuue6Re01N\npeVqaaKGDUVErxEATrOuZuCJJ55g7ty5LF68mLa2Nr72ta9x++23c+655zJggFMGjByoqYG6OuXK\naRcCQqj3Bw7sFBjz5wfLxVNdrRIMOVXzChMvP9swVhxOA2RHhxKmKYc8SaXkammihg1FRu8QALZB\nRTY20h6P03LhhdSWl7NnUxNHJZOcc9JJfPWGG/jKKD3vqaw5/3w47TSYPl0FEIwYATfe2NWvH4Ln\n6KmogNtui34AibLsoNcA6RYnEYWaKyqiKgZvMGRJzxcAGYOKAMpTKcqBp
 1pbaY/HKWtsRLz4Inzv\ne9Euxe2rkCOP9B6w/XL0VFaqpEaFqPkaVcCX1wAZjysh0KdP6da6NVHDhiKjRwuArVu38o9p0/jm\n9u04ZYcQQLllaI16Ke6k2rj8crj6avV5pjHQS9WSSMAdd8Ann3QOvlIqtVG+DItuRpVc8Bogm5vV\nqmnEiNKtoGWihg1FRo+LBG5ra2PRokXMnTuXxx9/nJ+2tvLfoJ/0qLoavvUtpXe20jQsWZLbwOoV\nzQpqZutU9tASGq2tXfNWV1WpFYC1b5ASisXsgTJ/virK4DRAOpV0LDVM1LAhDwSJBO5xAqC5uZkB\nAwYQi8WYMGEC/2evvRh6882IbHNCgLO65Stf0R9IvQa2TGpqlG/qhg2q3WOPhWHDugoA+77WbDjK\nWrv5ojcMkMX+GxhKnl4tAADeeOMNDj74YJVt02tQyZa+fZUuur1d7088e7YqOaZ7re0Cp6NDfc/J\nAyaZhIkTYe5c/1lz1DmDwqI3DJCmGLwhQoIIgB5pAxg5cmTni3gcrroKZswI7wA7dnR97Wc/CFp0\nxUoK57d/Y6PKKKpjWCwVD5SoDMzFRBT2E4MhC3qkACgYbgNpVDmqq6uVnWL5cn/DYil5oGQOkFYt\ngCjsFsVsEzEYIqbnCgD7H/vjj4OlW84Wt4E003c+F3uEnfJyFUMwf77755aPfKl6oEQZOWuicg29\nnB5pA3D8Yzc26uvgs8XPU8Wu+5USbr+9s49euX+sNBROPvC6XkClaGCN0m5RKjYRgyEgvdsG4BVN\n6kYiob4XizmvEjK9gNxm8X5RqZmqjWnTOgWCV+6fWEzts3ixs15cR28eZQRvVERptygVm4jBECE9\nTwB4/bGTSfWn3rJFvR47VpVXXLxYpWX4/HMlDF57TXn4HHJIZxyAfWBdsQJOPlkdJ5fka5kC4ctf\ndh+gd9/de0DSMSyWmoE1SrtFKdlEDIaIyEkACCFu
 AC4BPku/da2UcpHDficDvwTKgPuklDfnclxP\nvP7YDQ1q8J83r+ugN2yY0v1mDrw/+1nXBG2gBv/TT1fBW62tanbe0aGKsDvpjYMYGbMZoIMaMUvJ\nAyVKu0Wp2kQMhjDRLRzgtAE3ANN89ikD1gIHADFgFfAlnfazKgjjV0AkHu9a9SVIhaug1bCiLhXY\n00sRelVWy7X6WJRtGwwFhAAFYbQzJOTA4cB7Usp1UspW4GHgjMiOVlvrnjkSlDH0iy+UqqW5WU8X\nbLFggVL56Oxrt0U0NKihpaGh67FzIer2w8Zy5Zw9Wz3q9M+yW9TUKPWdEOqxpiZ3u0WUbRsMJUIY\nNoArhRATgZXA1VLKrRmf7wdssL3eCBwRwnGdkdJ9QLfT1qYSsa1e7W4kztQFL12qrzeO2shYSkbM\nXNwto7RblJpNxGAIGV8BIIR4FnCqjHIdcA8wG5Dpx9uASbl0SAgxGZgMMGTIkOANPPKIc9qETBoa\n4L77lB7fjUSiUxecSinbgc6+EL2RsVSMmGEUQYnSblFKNhGDIWR8BYCU8rs6DQkhfgs84fDRh8Bg\n2+tB6ffcjvcb4Deg4gB0jt2FJ5/U39dr8AeVgM0SQgsWKD98N6Ts6gIatZGxVIyYpbRSMRh6GTnZ\nAIQQA20vxwFvOuy2AhgmhBgqhIgB5wALczlu3pBSVe9qbvav0HXeeV1nsrW1ypPIiTCqWGXbvpcu\nPhs9vR+lslIxGHohudoAbhFCfA2lAloPTAEQQuyLcvccI6VsE0JcATyN8gh6QEr5Vo7HdWfsWPjT\nn8Jrz5qles24k0k45piu70UdeJVN+166eIgmLUKprFQMhl5Iz0sFsXUr7LFHeJ0QAmbNUlG72aRS\niDr1r277fqkPpHSOQs41LUIppqAwGEqY3p0KYvFiZdjTMQTrYM1Ss53RZ2NkDBLcpdu+ly6+udk9\nT1KuevpSTEFhMPQSep4AWLv
 WX3edWdAlkVAGX6dB0K5Pz4fbYNDawbr41dt1Iww9vXG3NBiKkp4n\nAPyKryQS8NxznSUdrQFpyBBl8PWbpUbpNujlMjljRmft4Gx0817XJR5Xws8pEV5YenrjbmkwFB09\nzwbgpXNOJODDD5XuOZNUSsUQWG6kY8fCOeeogTFfBUOC1g4Ooj/308VHZQMwGAx5pXfbAPx0zk6D\nv5Pa5dln1Yx76tT8FQzxczW1E1Q373ddwOjpDYZeRs8TABBM5+yldrnwwq52gaARrEEJUjs4G928\n33UxenqDoVfRMwUAhOMdE5VnDDh7+gSpHZytbt7ruhg9vcHQq+i5AkCXIGoXi1w9Y7wCsnRrBweN\nJjbFzw0GQwZGAARRu1jk4hmjkxzNrorJrB2cjW7eFD83GAwO9DwvoKB4eccI4awGysUzxsvTx62o\nfC7RxKb4ucHQqwjiBZSPgjDFjVdhkLq68AuGZJMczdLNX3+9egxy7CAFbwwGQ6/CqIDA2zvm7LPD\n9YzJd3I0k43TYDC4YASAhZsHTNieMV6ePmGkic7EZOM0GAwuGBVQvsl3Ldqo6xIYDIaSpXevAArl\nGpnP5GgmG6fBYHCh93oBOblGWoNiT3SNjLougcFgKAp6dy4gHcIoVF5qmChfg8GQQe+0ARjXSIPB\nYOilAsC4RhoMBkNuKiAhxCPAiPTLGuALKeXXHPZbD+wA2oE2Xf1UZBjXSIPBYMhNAEgpv289F0Lc\nBjhUFNnFcVLKz3M5Xmjk2xffYDAYipBQjMBCCAGcDRwfRnuRkw/XSJN902AwFDmhuIEKIY4BbndT\n7Qgh3ketDtqBOVLK33i0NRmYDDBkyJBvfPDBBzn3z5WoXCN7m4upwWAoGoK4gfoKACHEs8AAh4+u\nk1L+Jb3PPcB7UsrbXNrYT0r5oRBib+AZ4Eop5VK/zuUlG2jYmOybBoOhgIQaByCl/K7PwcqBWuAb\nHm18mH
 78VAixADgc8BUAJYmOi6nxxzcYDEVAGG6g3wVWSyk3On0ohKgWQvS1ngMnAm+GcNzixLiY\nGgyGEiEMAXAO8Hv7G0KIfYUQi9Iv9wH+JoRYBSwHnpRSPhXCcYsTy8XUCeNiajAYiojemwsoKrwq\njBkbgMFgiBhTEayQ5Dvds8FgMGRJ70wGFzX5TPdsMBgMWWIEQFSY7JsGg6HIMSogg8Fg6KUYAWAw\nGAy9FCMADAaDoZdiBIDBYDD0Uoo6DkAI8RmQbTa4/kBxpJ/uiulXMEy/gmH6FYye2K9/k1LupbNj\nUQuAXBBCrCx44RkHTL+CYfoVDNOvYPT2fhkVkMFgMPRSjAAwGAyGXkpPFgCuRWcKjOlXMEy/gmH6\nFYxe3a8eawMwGAwGgzc9eQVgMBgMBg9KWgAIIc4SQrwlhOgQQrhazIUQJwsh1ggh3hNCXGN7fw8h\nxDNCiHfTj7uH1C/fdoUQI4QQr9m27UKIqenPbhBCfGj7bEy++pXeb70Q4o30sVcG/X4U/RJCDBZC\nLBFC/DP9m//Y9llo18vtXrF9LoQQd6Y/f10IcZjud3NBo18/SPfnDSHEy0KIQ22fOf6eeezbsUKI\nbbbfZ4budyPu13/Y+vSmEKJdCLFH+rNIrpkQ4gEhxKdCCMeiWHm/v6SUJbsBhwAjgBeAUS77lAFr\ngQOAGLAK+FL6s1uAa9LPrwF+FlK/ArWb7uPHKP9dgBuAaRFcL61+AeuB/rmeV5j9AgYCh6Wf9wXe\nsf2OoVwvr3vFts8YYDEggG8Cf9f9bsT9+jawe/r5KVa/vH7PPPbtWOCJbL4bZb8y9j8NeD7qawYc\nAxwGvOnyeV7vr5JeAUgp35ZSrvHZ7XBUwfp1UspW4GHgjPRnZwAPpZ8/BJwZUteCtnsCsFZKmW3Q\nmy65nm/BrpeU8iMp5T/Sz3cAbwP7hXR8C697xd7XuVLxv0CNEGKg5ncj65eU8mUp5db
 0y/8FBoV0\n7Jz7FtF3w277XDIqG0aBlHIpsMVjl7zeXyUtADTZD9hge72RzoFjHynlR+nnH6PKV4ZB0Ha7ldUE\nrkwvAR8IS9USoF8SeFYI8aoQYnIW34+qXwAIIfYHvg783fZ2GNfL617x20fnu9kStO2LULNIC7ff\nM599+3b691kshPhywO9G2S+EEAngZOBR29tRXjMv8np/FX09ACHEs8AAh4+uk1L+JazjSCmlEELb\nJcqrX0HaFULEgNOB/7K9fQ8wG3UTzgZuAyblsV9HSSk/FELsDTwjhFidnrnofj+qfiGESKL+qFOl\nlNvTb2d9vXoaQojjUALgKNvbvr9nxPwDGCKlbEjbZ/4MDMvj8f04DXhJSmmfmRf6muWFohcAUsrv\n5tjEh8Bg2+tB6fcAPhFCDJRSfpReZn0aRr+EEEHaPQX4h5TyE1vbu54LIX4LPJHPfkkpP0w/fiqE\nWIBafi6lwNdLCFGBGvzrpZSP2drO+npl4HWv+O1TofHdbNHpF0KIrwL3AadIKTdb73v8nnnpm01Q\nI6VcJIT4tRCiv853o+yXjW4r8IivmRd5vb96gwpoBTBMCDE0Pds+B1iY/mwhcH76+flAWCuKIO12\n0z2mB0GLcYCjx0AU/RJCVAsh+lrPgRNtxy/Y9RJCCOB+4G0p5e0Zn4V1vbzuFXtfJ6a9Nb4JbEur\nr3S+my2+bQshhgCPAedJKd+xve/1e+arbwPSvx9CiMNR485mne9G2a90f/oB38F2z+XhmnmR3/sr\nbCt3PjfUn30j0AJ8Ajydfn9fYJFtvzEor5G1KNWR9f6ewHPAu8CzwB4h9cuxXYd+VaP+CP0yvj8P\neAN4Pf0jD8xXv1BeBqvS21vFcr1QKg2ZviavpbcxYV8vp3sFuBS4NP1cAL9Kf/4GNu8zt/sspGvk\n16/7gK22a7PS7/fMY9+uSB97FcpA/e1iuGbp1xcAD2d8L7Jrhp
 rsfQTsRI1dFxXy/jKRwAaDwdBL\n6Q0qIIPBYDA4YASAwWAw9FKMADAYDIZeihEABoPB0EsxAsBgMBh6KUYAGAwGQy/FCACDwWDopRgB\nYDAYDL2U/w9rzmhkh+BocQAAAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD8CAYAAAB+UHOxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXt4VNXV/787mcxMJoMJAioKvFyqgOKr1WAvIiLKTSqW\nGBWoIiISpLX12tcLF9+gta2Kvtr+FGsJShPBqrF4F7wU3retgC3eoVxqBcQLCSBJJvf1+2PPMScn\n5+yzz2Uumdmf5znPJHNu++yZWWvvtdZeixERFAqFQpF95KS6AQqFQqFIDUoBKBQKRZaiFIBCoVBk\nKUoBKBQKRZaiFIBCoVBkKUoBKBQKRZaiFIBCoVBkKUoBKBQKRZaiFIBCoVBkKQEnBzPGlgP4AYAv\niWhE/L0jAawGMBDAJwAuIaIDJudeAWBB/N87iehxu/v17t2bBg4c6KSJCoVCkdW88847+4moj8yx\nzEkqCMbYaAB1AJ7QKYBfA6glol8yxm4B0JOI/stw3pEANgMoBkAA3gFwupmi0FNcXEybN2+Wbp9C\noVBkO4yxd4ioWOZYRyYgIloPoNbw9oUAtNH84wB+aHLqBABriag2LvTXApjo5N4KhUKh8Bc/fABH\nE9G++N+fAzja5JjjAOzW/b8n/l4XGGNzGWObGWObv/rqKx+ap1AoFAozfHUCE7cneUovSkSPElEx\nERX36SNlxlIoFAqFCxw5gS34gjHWl4j2Mcb6AvjS5Ji9AMbo/u8H4C03N2tpacGePXvQ2Njo5nRF\nnHA4jH79+iEvLy/VTVEoFCnCDwWwBsAVAH4Zf/2TyTGvAvgFY6xn/P/xAG51c7M9e/agR48eGDhw\nIBhjbi6R9RARampqsGfPHgwaNCjVzVEo0p5YDKiuBnbuBIYMAUpKgHA41a3yjtMw0CfBR/K9GWN7\nACwGF/xPMcauAvBvAJfEjy0GMI+I5hBRLWNsCYBN8
 UuVE5HRmSxFY2OjEv4eYYyhV69eUD4WhaIr\nRmE/YABwwQVAaytQXw8UFAA//jHw2mvAyJGpbq03HCkAIppusetck2M3A5ij+385gOWOWmeBEv7e\nUX2oUHRl0yZg/PjOwr6+HtBHy9fV8dfx44F9+7r3TECtBFYoFArwkf/48cDBg1zIE3W8mtHaCjz7\nbHLb6DdKATjkk08+wYgRI5J2vzvuuAP33ntv0u6nUGQr1dVcqMtSXw/s2pW49iQDpQAyjFYn32CF\nQvENO3dyoS5LQQEweHDi2pMMlAJwQWtrK370ox9h+PDhKC0tRUNDA15//XV8+9vfxsknn4zZs2ej\nqakJADBw4EDs378fALB582aMGTMGAB/Zz549G2PGjMHgwYPx4IMPfnP9u+66CyeccAJGjRqFbdu2\nffP+7373O4wcORKnnHIKLrroIjQ0NAAAZs2ahXnz5uE73/kOfv7zn+P444//xsHb3t6Ob33rW8rh\nq1DYMGQIF+qyBAI8Gqg740cYaMq47rrrsGXLFl+veeqpp+KBBx4QHrNt2zb8/ve/x5lnnonZs2dj\n6dKlWLZsGV5//XWccMIJmDlzJh5++GFcd911wuts3boVb775Jg4fPoyhQ4fimmuuwXvvvYdVq1Zh\ny5YtaG1txWmnnYbTTz8dAFBSUoKrr74aALBgwQL8/ve/x7XXXguAh8f+5S9/QW5uLgoLC1FZWYnr\nrrsO69atwymnnAK1qE6RjTgJ3ywp4dE9ZjAGRCJAQwNXEoEAjwKyulZ3CRtVMwAX9O/fH2eeeSYA\n4LLLLsPrr7+OQYMG4YQTTgAAXHHFFVi/fr3tdSZPnoxQKITevXvjqKOOwhdffIENGzZg6tSpiEQi\nOOKIIzBlypRvjv/ggw9w1lln4eSTT0ZlZSU+/PDDb/ZdfPHFyM3NBQDMnj0bTzzxBABg+fLluPLK\nK317doWiu7BpE3DssUBZGbB4
 MX/t25e/b0Y4zIV6UREQjXKhH43y///8Z+DRR4HycmDZMh79YxUC\n6vS+qaRbzwDsRuqJwhhCWVRUhJqaGtNjA4EA2tvbAaDL6uVQKPTN37m5ubb2+1mzZuG5557DKaec\nghUrVuCtt976Zl+Bbu7av39/HH300XjjjTewceNGVFZWSj2XQpEp6CN6NGTCN0eOBD77jI/ed+3i\nNn4no3e3900Vagbggk8//RR//etfAQBVVVUoLi7GJ598gh07dgAAVq5cibPPPhsA9wG88847AIBn\nnnnG9tqjR4/Gc889h1gshsOHD+P555//Zt/hw4fRt29ftLS02Ar1OXPm4LLLLus0M1AosgVRRI9d\n+GZ+PjBjBrBgAX91IrCrq4HmZvN9zc3pFzaqFIALhg4dit/+9rcYPnw4Dhw4gOuvvx4VFRW4+OKL\ncfLJJyMnJwfz5s0DACxevBg/+9nPUFxcLCWITzvtNFx66aU45ZRTMGnSJIzUzTOXLFmC73znOzjz\nzDMxbNgw4XWmTJmCuro6Zf5RZCWiiJ5Ehm9u3cr9BGY0NAD//Gdi7usaIkrb7fTTTycjH330UZf3\nFF3ZtGkTjRo1SniM6ktFplJZSRSNEvFlXJ23aJTvTwTz55vfU9vmz0/MffUA2EySMlbNADKQX/7y\nl7joootw9913p7opigwiFgOqqoAlS/hrOifkLSnhkTpmJDJ8s1cv8f7evRNzX7d0ayewwpxbbrkF\nt9xyS6qbocggzHLkpHNCNC2ix9hmu/BNrwwbxn0IsVjXffn5wNChHf+nQ6ioo5rAycasJvDHH3+M\nYcOGqWRmHiEibN26FcOHD091UxRpTizGwxr1kS0aRUXpF9miRxOybiJ63NDYyEM+7frKTKFqysmr\nQnVSE7jbzQDC4TBqamrQq1cvpQRcQvF6AOF0/dVmCOkwwvMDmYiaGTOS2yZZtIieZCEz80inUNFu\npwD69eu
 HPXv2qNQGHtEqgikSQzqZTLwqolRF1HRX7NYSpJNC7XYKIC8vT1WxUqQ16TTC80MRaTly\ntGfQkwkJ0RKBaOaRTgpVRQEpFD7jZRGSn1jltz94kL8vG8WTqoia7oZslJQo6VyyFapSAAqFz6TL\nCM8vRSTKkZPIiJruhJP8P+mkULudCUihSHfSxWTipyLymiMnk3Fq8ktViKoZnhUAY2wogNW6twYD\nWERED+iOGQPgTwD+FX/rWSIq93pvhSIdEaUVTuYIz29FZBdR0x2jnvxosxunbrooVM8KgIi2ATgV\nABhjuQD2Aqg2OXQDEf3A6/0UinQnXUZ4yVRE6RT1JItdm2WVg5OZVropSb9NQOcC2ElE//b5ugpF\ntyIdRnjJUkTpFPUki12bn38euOAC3m91dUAoBFx1FXDbbcDNN3d+HtmZVjoqSV9XAjPGlgP4OxH9\nxvD+GADPANgD4DMANxHRh12v0BmzlcAKhcIZiV4NW1XFnZ5mAjAa5QVU0m2hWFUVMGeOdcoGxqyz\nemrOb01oy6z+JUreauqUrARmjAUBTAFwq8nuvwP4DyKqY4ydD+A5AMdbXGcugLkAMGDAAL+ap1Bk\nLYleDZsuUU+yxGLAH/9oLvy1/Xl51udrYbSa0NZmWuPGcWXQ1MRnDNr74TBXOOmy+EuPn2Ggk8BH\n/18YdxDR10RUF//7JQB5jDHTvHhE9CgRFRNRsapjq1CkP+kU126HFq754ovi41paxPutwmjjxf++\nedVIVyXppwKYDuBJsx2MsWNYPHEPY+yM+H3NaygqFIpuRTrFtYvQ2/3tBLxoBgB0FtqxGDB2LHDo\nUMd1W1r4/6NGAStWAP37p6eS9MUExBgrADAOQJnuvXkAQESPACgFcA1jrBVADMA0Suc0pAqFQpp0\niXqyQxSuqUfzAYiUhF5or15t7v8AeBnIefN4H1jlrkylkvRFARBRPYBehvce0f39GwC/
 MZ6nUCgy\ng3SIerJDZIbREwpxH8G4cdbH6IW2nTmpqYlv2uppo5Jcs4abk1IRGqpWAisUCl9Iduplp4jCNQEu\n+PPz+axl+3Z+rJXCuOEGd0L6V78C3n2X1w4eNowL+ylTUhcaqnIBKRSKrEDkqwiHgUce4ZE9I0fy\n0bhVGCjQ2ZwzebLc/evqgJ/9DHjiCeDNN/nreed5T9bnBTUDUCgUaUciVsza+SpGjOgwxXz+ORCJ\nmM8AolFu4tKvrwiH5QS2/hirmQiQvNBQpQAUCkVakcgVsyNGAPff32G3nzwZmDYNeP99Hh6qv6fV\nDCAQAAYM6Hy85uTNy+OOX6/U1SUnNFQpAIVCkRRkRvWJTCthpljWreNtmTLF/J6M8ZlAQ0Nnp+0F\nF3Q+XltUFggAM2fyhV/aauKCAn7PpiZu5pEhFEpOaKhSAAqFIuGYCd+rrwYuvxwYPbpDGSSqXKJI\nsUycCORYeEMLCrhA79u3I7Lp2Wet25iTA5xzDvDgg50jopqbgWuvFZt99DCWnNBQpQAUCkVCEQnf\nZcuAP/yhw8STqBWzdorFymxTX8+F/4IFHc9SXW0tyLU2GiOiGhuB66+Xb+9ttyUnFFQpAIUiw0h0\nymGn17dbgKUJ/PHjuX0+EcV0RIqluRkIBs2VgFk2T6scQqI2Gh3QoplAURHPOJoMlAJQKDKIDRu4\nSUMb1fodV+7GQSu7AEtTEnZpJdwoOLuUzUTmCkB/T+MsRtRGwLyd+sVyRMDSpSlePU1Eabudfvrp\npFAo5Fi/nogxIi5aOm9FRUSxmLfrNzTw6zi9fmUlUTRqfp5+Y4xo0SKi8nKicJhvjPFzi4qINm7k\nW1ERf8+4T0QsZt32wkKiDRs6XzcYJIpE+PsyzxAOd26HbDsbGvi1lyzhr14/IyIiAJtJUsamXMiL\nNqUAFAo5Ghq4wLISUAUFXMB4QSQEo1Hr64uEr36LRPim3SMU4oK
 1vJxfo6bG+hllFNzGjebt79GD\n71u/nl8/GOzoM01ol5dbK1eAqLS04/5uFaVfOFEAaiWwQpEByNjZvcaVu3XQavbvoiK+iMqKWIyH\nTWpmmqYm7jxduhTYvBk47jjr2Hyr9Mx6RowwNy8dPszNOxdcwK+vmYLq6ztW5YqyeUajwNSpHWYb\nmUgmK5qamvDMM8/g7rvvFj+MTygfgEKRAezcKV6AFAx6jyv3UmRenyzujTeAlSv5mLilpcMGT2Tu\nYG1pASZMEK+0lam9KxLMjY3WMfqyvgkNaUUZbyTt2IFPcnPx4J49eOKpp1BbW4tBgwbhxhtvRDAY\ntHxmP1AKQKHIAIYM4SNRq+gSP1IOey0yn58PHH88v0YwyNsaDHLBO306sHy5+Xn19dbCVyMUAvr1\n4wuw1q/nCka/EOvHPwYuvdRaMNsplz175FNeSynKTZvQPm4cWhsbEWhqQm8AiwF8d8QInDZ5MoaM\nH48cY1WZBOBrTWC/UTWBFQo5RHVpGeNC6ssvvYeGmkUBaULQLsooFrOuixuJ8HaaCWirEE3jMZGI\nOMRSdI9wmCuipqau+/R1jWXqK4trBBN+9+DTmHjVjxC1KziQl+cqfCslNYEVCkXqMEt0lpfHhfMD\nDwAXX8xNKfX1XFhefTXw6qu8YpUTnOT9N5phmpvFK2itBrza6F+kBJqb7ZWE6B4iBSAdfho/ILxz\nJ167YSTGL52A1laG+nogP78NbW1NILoQz85ch4lW1WE0NC01bhzPTJeouFBZb3EqNhUFpFA4wxhW\nWFtrHZHCWEeYo9+YhUGGw9ZRNIwRlZWZh06uXSuOwJHdRPewCzG1Des0OaDuiKPpJ5NW0jHH/IaA\n6ZSX14Muvvhi2nbZZdTu5IHKyx31PRxEASkTkEKRxnhd1VtVBcyda237jkSAmhr/VwpbmXqs0Mws\nU6d2nV08+ywwZ454Ba7Xe2jPb2biIbJ+nq
 IiYN+uGMKDzQ+oBXDBaadhxuzZmD59Oo488kj+oZSV\nyScGCoeBAwekPyQnJqCUj/JFm5oBKLIZp4uJysu7LiYqLxcPLoNB7+sDjMgu/JKNj7eLwffjHm6f\nJxolqpz/v9RqsUChNRLp2sGyCyO0LRx29CHBwQxA+QAUijRENi2y0SkbiXTOstm/v9iJ2tJiHz5p\nNfC0OlY29YMeUYlFu1KOduj9qUR8AG71fGbPJHqeurp2rFr5f5hmsUAhNxbrukBC77BpbLSvJNPU\nlLjiALKawm4D8AmA9wFsgYkGAsAAPAhgB4D3AJxmd001A1BkKzKrbkUrTrXjior4ilrRMdrg0m7G\noZ9plJdbH+tmBrBkiXVfxGLiVc56G7++PZEIt/lrsyK757PaX15OFI22W9z3EE3pfS01WXWyaIl0\nQwNRRYXYOWJ3DRPM5K/V5rcC6C3Yfz6Al+OK4LsA3ra7plIAimxFZPZgrMPJKyNoRcdoZhG79AX6\nXDl2ZpYDB5xZOGTkW1mZ+Bp5eUTr1lnn1RE9XzhMtGyZ4PmjLVSIA6b7evRoodgBgUlHNkdFYaH9\nhySJEwWQzFQQFwJ4It7GvwEoYoz1TeL9FYqkE4txk8OSJfxVttC3ZvYwQ1tM5MTUsnAhNw8FgzwW\nPhrlDkxtEZNd+oIJEzqKl4tobQVeeqlz6gftflaRj5r5asUK634aPdq6PwAe4llayheaLVjAY/b1\nph27VcA/+Ym107q1rgE34l4UoRZRfA2GNkTxNYrYQbz+UhvCRWHzB9Z3sIiRI7lNr7ycH6vVl3Ry\nDZf46QMgAK8xxgjAMiJ61LD/OAC7df/vib+3z8c2KBRpg5fatjKrbp99Vs42rsX+799vHf1il74g\nL098D/2xu3ZxAWxcLzBgAM+3Y1ys1djII5U0otGu/STqD4CbyZuarMtG2ilL0ZqsehSAAfgMx6Ea\nU7ELgzEYu1ASeQ3hT
 x8EMMPZAgkz8vO5lr7pJvfXcIPsVMFuA3Bc/PUoAO8CGG3Y/wKAUbr/XwdQ\nbHKduQA2A9g8YMAA6WmPQpFO+JER0s5mHYuJLQdOTCyiaCEtO6Yf5hxZs7dZP2n9IevT0OPGL/HN\nNXGIKjG96w7NFpdmIBUmICLaG3/9EkA1gDMMh+wF0F/3f7/4e8brPEpExURU3KdPH7+ap1AkFdmM\nkCITkTaoXLaMWweWLeOjW21UHA4DN95o3xa7PD2xGHDffeLzReYXJ/fKz+ezEbvcPkDXzJkjRvCK\nYUOGWJ9jlZW0pETunmYE0IoSmKTw9FKiLE3wxQTEGCsAkENEh+N/jwdQbjhsDYCfMMZWAfgOgENE\npMw/ioxEJiOkjInIWFvWDMb4kNQMLeLQrmRjW5v1/htvBB56SHx/Le3E88/bWyxkfRdaP8ViwL33\nAr/4BX9f5EexL8lIqK9vR0tLDng8ipF2hNGEJgRRgHoE0IrXMAFhCHJEdGP88gEcDaCacS9PAEAV\nEb3CGJsHAET0CICXwCOBdgBoAHClT/dWKIQkukauGXYZIfv1k4vz93KfcBh4+GF7f4OdQA4GzTNh\nAtx2TsTXGeTlcRu/nY9DNq5fSxPdty9w6JD4WA0rmbx9+3b86U+Po6BgNQ4e/D6ARwDkdzmuEAfx\nAK7HHvTndn48y4V/OMwvnrLajQlC1laUik2FgSq84raEoFdEiz2Lirgd3E11Laf3kfE1yFb60ucZ\nqqiw9j/Y3Vd2IWxRkZyPg3+u7VQUaaKNZb/7Jgb00KFD9Nhjj9GZZ55JACgnJ4fOP/98euqpp+h/\n/7ep8/ci3ExFqKWNKDbvhIoK/2s3ipZwewCqJKRCkfrSfCLlIxPn78d9ZHCjRNyWh9S3WSTcGSNa\nuFDOcXvuyINUGZlDsYJe1M4YteTnU10wSKNCIQJAw4YNo1/96le0d+/eTm1oaCCqrGiiJaVbqHLq\n
 HymW3zN5X5YEjkycKACVCkKRscg4Yu3s614QRQZu3+6+upaT+8hglkrazsrhtjykvs0PPABcc425\nTb+gAPj4Y3tfQTRKmP3hTZjR8Ng37wViMQQAvBoMYt+CBRiclwfWrx9w5JGdzs3/YBNmXK976Px8\n7tAIh3mjEmXqkc3zkQSUAlBkLF6FlB9YOXG9VteSvY8sTpWIl/KQGrt3m+ffBzo+N1tfQXMDJrZW\nme6KNDdjyD33cAeF0cNuJoS1fD6M8Zj8oUPlNKnIyeS0NmUyRiY6lAJQZCx+CKlE4WbUnWicKBGv\nCiwW43VO8vLME9UVFACTJwPr1lldgQAcwiXN41AEi0rxQIeGMY6wRUI4J4cLf5nOEIVyaffT77v6\nauDEE621WrJGJnGUAlB0G5xG8/g9yvYbr6YbL3iJjNLOvfTSrrV3ZRSYJjNbWqyzlAYCwLRpwEkn\nace2x2cFzQDaEQotxYwZn+G/BkwGu2+rfKrQxkaeKhXwPj0UmXLGjeMdY7ZPVOMkHE7uyETWWZCK\nTTmBFRpufWapigJKZ7z0idm5xqybImQzmG7cSFRXV0ePP/44jR49gYDpBCygESPuooqKJ6m+vp5f\n0GlufW1zs5zYiMgTHgrJLXc2834fOGB/bwFQTmBFJuHFZ5bKUXaycJrD321fis5dvZo7de36VWR5\nCQaBmTMJU6f+Hx55pAJPPfUU6urqMGTIENy96EeY06sXeh86BATbuZkGsC6GbFcg2Mr5AMhPD0VO\nJtH1ReTlcTPR1KnJ+aLKaopUbGoGoCDyHnKYTLyGdjs9XzSaN7uWl77043MQV/dqoyOPvI8AUDQa\npdmzZ9OGDRuo/e237acs2sMuWkSUn+9s1B0MupseJmIGYDYVcgjUDECRSWwVmHiT7DMT4iX7p5vz\nRSPyc8/lg+S2ts7XuvRSedO3cWaxbZt3s7l4FXAdjjmmAQ888ARKSkpQUFBgX
 mBYO3nMGGDvXp4y\nWfNgV1UBubn2DdFDBCxaBJxwgrNRd0kJr+1rRiDAR/Oy+b+NJCksVCkARVqzaZM4UVmqo3k0vIZ2\nuzlfZE45fLjz/9q1Vq6Ui4wyU0bt7VzOmlU/FH4OOk0ytd+3MA+lALrmlz7iiAK8886Czs8pesiG\nBuC444C33urQkG7qUebmcuHvNPSSyLrIQU4OT4xklv/aCQkOC1UKQJG2aELRotwqgPSI5gG8h3a7\nOd+NrGOMC3IztL4UKSMredfpc9BPHQBg6VK0t7SA1dejnTE8S0sxEa+BBcJoawt3RA9d+xLClz/B\nz5k8mYcB2T1kQ0NnDemmgLDbmrvV1VwJmEEEfPpphwPq978H3njD+T0SPMVVCkCRtoiEIsArXKVL\nPi6vi87cnO9G1tXXc6vF6tXW6w+qqqz7XStWlZNjsXZBN3WgeMMY8E3e+QIinIfN+PqI4Xjufz7F\nrj0Mg2knSn79XYSX7O+40dNPA/PmAWeeCYRCYlNKU1OHhrSrHGOG22mkzIemmaZ27hQrgEDAvNMT\nPMVVCkCRMuyiV0S/L8aAm2+Ws6371R4RXheduTnfjawDgO9+l+fVd1MdrLGxY5Fsl3NjMdD48WDx\nqYPFZAEAEGmvx4zg08CNU4Fji4E6k3qMTU1yo+ZYjDsogI6ooHHjvKcQtcPJhzZkCC91ZnUskbkC\nSPQUV9ZbnIpNRQFlLjKx6MmM/klFQjU/zje2WybApKJC3BY3/b53717607RpVCfbCH1ley/RMto2\nf37nBjU08JCjcJhvjPEFC4zxKCE/FoU4+dDsjt2wwbcFK1DZQBXpjGyWTpnfl5uwS+M5tbXes4aa\nyRunv2G3SqihgWjZMqK8PHm5K0JUarLz5xOjp556iiZNmkQ5OTm0AKA2J2GO2ofgVfgDRIsXW3eO\nPo1zba2/aZ2dfGh2xxrb6rJtSgEo0honI0zRb8aNwLRa
 yWoVOi6b2li7JtARAl5e7n4dgBMZsHEj\nfwYnctfuej16mJ/79tvttGnTJpo/fz717NmTAFC/fv3o9ttvp3333SdfeFfTJH7MACKRxCwGkR1d\nOPnQzI71uS6AUgCKtMZpLnyr34zsqF07f+FCeUEpO2JOdM0BO9lgl1rBaZtE1wuHYzR8+LcJAIXD\nYZoxYwa99tpr1Nrayk+Oxcw1h74zzSrbu0nl4HdHG0lWDpEE3MeJAlBOYEXScerwNMtSWVXFk4mZ\noQ+b1MezuwnFtnPgJjKzr8zCMLtIKY1wWL4+sOXzNDbj+1+ciYeuOg2n33knio45pvMBmkg2IxQC\nbrmFx9tPmgS8/DLwyiv8y/D889xpa7doKhrlMftNTfzYQIDnj5ApROyEZOXrT4O6ADn2hygU/lJS\nwn+7ZsgGPaxfbx+Bp/99uV2HY9eeRNQciMWAFSuA0aM72k7EXw8e5M+kyUqZtQBabeB9++yjpnbs\nINTXmwvxNhRgYG0Rzl29GkXDh3MNpae62vrCeXlc+B9/PNeoZWXA4sX89YILgBde4ErCisJC4De/\n4dpJe/jWVr4OYNKkjrbEYnx0sGQJf3WzEldGq8tg1xa/7uMBNQPQkYri4dmI11z4sRhf0WpFJMJl\njOzoWE9+vrNiUH7XHNBG/bGYdT4x/czCbi1AJNJ5oawVX375JSorK/HYY1+A6HYAPbocU4B6DMZO\n61GqnTb84AOe6Ey/sk+7Vmkp73Czhw6FeHmw4cPNr19XB4wdy2cV2spbN7k4NPzQ6jLTt3SoWCRr\nK7LaAPQH8CaAjwB8COBnJseMAXAIwJb4tkjm2sn0AWRb2uAE1aN21QanQQ8iJ7LmE4zF7BKPWZ+7\naJF8e/woyq7vDxlzuN4vIbp/JCLOLNzc3EzV1dV04YUXUiAQIABUXDyK8vMbzZ8HNRSDLo2y0aMs\n+mAiEZ50zeqhwmHrFM3RKA/ztAt
 zsvLkO/0gvMYfyzqGEhTnjGQ6gQH0BXBa/O8eAP4J4ETDMWMA\nvOD02slSAKkuHp5suruysxPsZWX8ODtF4dfvzq/+lG2vk0gpM7Zs2ULXXXcd9enThwDQMcccQzff\nfDN9+OGHXa+HNoriEBWhhjaiuHNDjB5ykTZyqomN5xYX2x+Xm+vPh+pVq8sKdj9HDzqcKADPJiAi\n2gdgX/zvw4yxjwEcF58RdAvSqERnwkkDv5NnRGaPaJTbzgF3K2VFM28rE6G+5sC2bcD+/UDv3rzw\n+8kn82NkzIs7d8r5Kox+iZEj+bkLF/LMqcOGAXfdxZNkauzfvx9VVVVYsWIF/vGPfyAYDGLKlCmY\nNWsWJkzKWSbVAAAgAElEQVSYgIDOKdOphkL1+xj8/P+gpKkKYRjMM0Ybl5Vtr72di7VYzPqhwmF+\njJkJKBIB3nvPvmPa2szfd2pO0T9HSws/PxjkHS/jcJY17aRDXVBZTSGzARgI4FMARxjeHwOgBsC7\nAF4GcJLgGnMBbAawecCAAa40oFOchiV2Z7pTbn0rnAycrOL+rcJBrfpAZpRtdcyKFXIj9IoK8QA3\nFDI/r+O+7cTQTtFgIxVFmugvb9bRmjVrqKSkhPLy8ggAnX766fTQQw/R/v37/e9sDb1tr6KC6Ic/\ntB+9FxVZrz6LRIgKCuyvYWUicrNOoKGBxw3n5XXMLGSndk5/ZD4tANNAKtYBAIgCeAdAicm+IwBE\n43+fD2C7zDWTZQLKBKEoS6YoOydmD+Pv68ABZzJNxkQoOsaqv433slMAc+c6a1shauk0hOioo46i\nG264gd577z3/O1vkTNLOs1voFYmIV/aVldmbkES2M6dlFrV2iJSVSEgnyLQjS9IVAHhy71cB3CB5\n/CcAetsdlywFkOLPK6kkStn56VROxAJMI04UiEyf+eFvcKOc+X3bza+PQ/R4aBY1f/21f6XK9J29\nfn1n525BQW
 fFIOPRNnqqze4j4/UvL7d2Aufny3+xZdrtdHl4kh1tSVUA4En/ngDwgOCYYwCw+N9n\nxM1EzO7aKgrIfxKh7Pzsu2R+DrIKREYwu4k4Mgp1p8q5paWFLrtsGwFt5tdHKy0J/jdvnJsRvIj1\n68VTm4oKsdC2smeZIRPq5NfUVkaTy17PZ9OOLE4UgB/rAM4EcDmA9xljW+Lv3QZgQNzH8AiAUgDX\nMMZaAcQATIs3NG1I1+Lhfq9N8Nvv5KdTORkOajf9KRvr7zQ3v9GHKnJa6x2/H3/8MVasWIGVK1di\n374xCGIZmq3i9pu3Ab94tvMiJK2RY8d25KF3EjcfiwETJ3JxaEZLC/Dii+IVahdcwBdzyHygoi/t\nmjXASy9xJ3EwaO5ENna06Esgs7JOdoGH2RL2dENWU6Riy/ZcQIkcDfs1OPHTpJRo81RZWYc/0Ul/\nysya3ERAms24rD7zdesO0cMPP0xnnHEGAaDc3FyaMmUKrV79JyqKCOL2Q4XW8fVWm91UsLJSHNMP\nEI0da/1hBoM8rt+rGcqYQlnmeex+VDIzgDS3C0Mlg+v+dJe1CX46lUWZgRkjKi01t1TI+CFFv2lR\nfxqVRyKjgIz3/O+FjXT3BVW08sTTaGYgQCGATj75ZFq6dCl9/vnnHffd0EhF7ABFcYgYWjvH7bvJ\ntGmnbWVSOOfni23pen+BG2Rt9cZ0y140OcAjldLcLuxEAahUEGlKd1mbIDKPhEJAv37+3IeIh2A/\n80xnSwVgveJ+xIiuJiUzrPrTuJo/EuEh7XPn8rUGmuVAb1G4/35+7p49nc2Il1wib1789NNtOPDa\n3fjpE08glwgFAEoDASwPh5Hzve+BHX00z40TZ+SoED778/uonrgMu1r7Y3DzNpQUvIpwXhswZiLw\n3HPOOtsubl5U3UojJwe44Qbgnnu6VqjX7gG4t+2JfiDhMPCDHwBTp3buaNkfldHcpOUouu0
 2XoYu\n1XZhP5HVFKnYsnkG0F3CNf0aMDlNa6wN2kSFS+z8kGb9KZM62olFQX9NkZ/14MGD9Oijj9LZZ5xB\nVwDU4GRka7yR5pUudGH+kZkByKRwZozn1LD6gIz3cuqMdvMDcXJOihy4fgBlAur+dKe1CV7Dponc\nhVGK0seEQkRTp8pF5mj9KWMu0o6vqOCblYVFe2aRgmhtbaW1a9fSjBkzKBwOUzFAB3NyqCUQoHZZ\nDWi1EMupNnX6gdlVoSko4HZ+mYiasjLnzi43i63mz7f2XaTbj8oDSgFkAN1tbUJFhTiXl91vy00Y\npd2WlydXAKaoSFwW0kxmiZSPXklYXTMcbqB+/b5FAKioqIh+NncutYiKqTjpWFltmp9v79gQUVtr\n3cGMEV11lf2HWlAgN9Uy4mY5uGg1cTr+qFziRAGoegBpihb5VlTEza2M8deiouSlCRFRW8tt7eee\ny1+3bweam82PNTMpG1Ol9+/P7fd+0tIiTj+Tn9/Rny+/LJ86mohHVVqlawb4M7/4ovU1Gxtb0KvX\n1Vi9ejX27duHB84+GwEiuQbob2LWsdXVcvGowSDwwAM8pPOii4CHHpIrGqDRsycv6sJY131EwJNP\ncseJCCLuLzBDlBNf9geijy02C+9Mpx9VClBO4DQmXdcmPP44cOWV/LcLAG+8wV9DIbkwbLNU6bm5\niWmr5qQ1gzHgX//iv/9XXrEP/3ZCQQFA1I66Oga+VtJ47x4oLf05Lrkk/oZM/LnZTcw61q4ISjDI\nt/Z27qjVPoR164CTTnKWO3/3busogJwcfg8rCguBadOARx8132/njJb5gaxebf0FCAaBmTOB++5L\n/Y8qRagZQJqjrSVZsIC/pvp7WlvbWfjrsRoR6xcxGat0EfHXQ4esSzwaCQbl+6GxkRejMiMnh68h\nAjqimfyitTWGt966GYD5SLyggHVeS+SmAVYda6cAcnP5dviwuNyYDH
 aZLy+/vPMoXatNWV4OfP45\nD6eyem4nFXXMvpCbNgHXXGP9xWxpAfr2Tf2PKpXI2opSsWWzDyCViAIy5s8Xm3SDQbFJWWSetltb\npB0zf758hI/omozx9Up2CeLkt3ZirJGAGgJG0rnnTqZIpEnO5Oy0OLqWQE2mY41bKGTtvQ6HeefK\nIvKEGyN8zCJqvDi77JLU+ZHTpxsC5QRWuMUurHHsWPFvaswYcfScnbPXTgnIrtfRX88uk7BowZaz\nKMp6Ouqom+mOO35Ju3fvlupPy863u9ltt3XW0gsX+udFD4flHMEbN4rDPGUdq26WvNst6pIZIWSQ\n41ePUgAKV8gslLSbAcyfL76HaKAqCggBuq4pkJGX4bC8XNSigfQKbO5c0TntxBOxfU3BYB099ti7\n1N7ebtqv0iHl2sGlpdbaxyx6JxKxzoZp3EQzACvhaJwW2oVNOV3l6zTu3i4MtLRU/MHLKrluiFIA\nLkmHOrle8fIMMqHVBw6I19LYpV23m/Eb07uEw3wrL7evPbJsmbUM1OSkSCaYWQQWLRIrgOHDP6Pl\nyxv9/664SS4kq+kKC+2nT3pTkNOqOqGQMzOSG+wWdZWWWn+ZnZq5uhlOFICKAopjFpkikxgxnZB9\nBqtkiDKV7IqKgIqKro5gxniKhIceEmfZJOKBJ7/4Bf+/qalzYsdPPwWuvRaoqeFlFYcOFUc+6RMu\nVlVZRxNFIjzgY+vWjqglq2fsaCsB+CdycweirS1kck2GBQv6mqfk8JrGVVReEQAaGrqek5/PX3Ny\n+PHhMHfo5ufz9ujTvgLcAWvl8G1s5A7UIUOAKVPMU7Ra0dzMc2EkErsUrZMn86gmM8JhHn2kUDMA\nou6TeE1ETY271AWa2aWsjJtvrOzlxkFTTQ0//txz+WDriCPsTbjG+iHBYMfo3jjyd5P5VGalv8ws\n59NPP6U777yTvvWtbxEQIqDW2XfDasRcVuZ8W
 mY0jSxaJH7IRYs6H2+0aRlLkNk5OWTLMdpNpfxG\nxnmcLUU+DECZgJzRndIu6NGEcHExUSBg/3u0C4yIRMRWBLO8PrLKU1Q/RGSRcKKAZT5HcW2RJho7\n9nxijBEAGjNmDK1YsYLeeqteXo7YdbLXLJh+flllPOkyoVlePjQvOEnE1A1z+rjFiQJQJiDImT7S\nDeNiLBHaM4iSIQIdVgXGzK976FDX5I0yCRanThXXD2lsNF9Mqr+GTOZTmYIqnS0rhPp6IBBoREtL\nExoaxmHXrv1YvHgxZs6ciUGDBn1zvvSCPLtOdpoF02hKOv98/jCih5RF64xRo6yXcbe08IUXZvvz\n8/kHp5mcvFQWcoPMQjAnRVn8rr7UDVAKAPIVn9KFvXuBWbPkj9eeQXaxaTAItLWZyzGjQJZRnnYy\nUZRSoa4OWL9e7jcsW+3s2GP34oYbnsTDD3+OurowGNuLyy4L4Kqr7sHo0aORY5KaQFqOyHayjGYz\nc+oEAjx9w3XXmVfHevZZZwJsxAjxMmzN72CmAEIh/gG//LK7pep+CFy/qm5lghPQDbJThVRsqih8\nVzZudD4r156hosL5bN64ualja1c/JDdXbIqORLyZzfm6gRitWrWKJkyYQDk5OQSAzjrrLFq+fDl9\n/fXX/n1AThZkWVW40R5C9KU02vbdOlEqK8U2/kjEHweNEZEzKtmmmkxwAuqA8gE4pzv4i9xk+dUv\nGJVVAIGAtUAuKOhsZpZRnnYyUQtrt9pvvKdZv5iFvra3t9Pbb79N8+bNo6KiIgJAAwYMoIULF9L2\n7du9fRBWsbZOVvRqixScLpk22vq9CDC7lXllZZ2f2Q9but0XOdk/vu7qBLTAiQLwxQTEGJsI4H8A\n5AJ4jIh+adgfAvAEgNMB1AC4lIg+8ePefpGuidf02JlSjEQi3FxUVMT/371b7rxgkOfPMTPNNDQA\nAwZ0/C9jdhHZ5hnjx/3h
 D8CyZebHNDRY+2E6Zu6E+jqgINiM+XMIs2Y9ibV/vhcfffQR8vPzcdFF\nF2HWrFk455xzTE080tiZCrQOGTPGPFRTjxaCqdke9X4BJ44pO0fMqlX8QzUztdjZP0eP5n/7WeDc\n7ots1h+JpDs6Af1CVlNYbeBCfyeAwQCCAN4FcKLhmPkAHon/PQ3Aaplrq5XAnSkrkxtYWg2gZKwT\njPEZvyhqx2xQaTdANM6wgsEO64LWNitLhNUgTDSQLEQNzTzpdPrd735HBw8e9OcDcDLSXrhQ7sOy\nelAno1K7+Ndw2Hpqmwr7p2zxh2SNvrN4BuBHNtAzAOwgol1E1AxgFYALDcdcCODx+N9PAziXMau4\nj+RhzEnvJAlisonFgJUr7Y8rKeEjabO07iUl1gEkAJ8xrF/Pg0J277YeeDU3d07TrvflWc2ctBnW\nsmU8EWRFBV/sNWpUR9ussnZaBbc8+yyhucl8JNmGACb869uYc9llKNTVz3WF9kWZOdP6S2LMXT9s\nWEctWVn0o03Rh2XsEFEmUSLeZqusn6koPCGb+TRZo28nfZ1pyGoKqw1AKbjZR/v/cgC/MRzzAYB+\nuv93Auhtd+1EzgC6g81fj52vLhAg2rfP/jrG/DlaWhh9qoWGBl5OUTQ4W7y46/W89qPstT7//HO6\n99576aijHiKei8dk4ItWWhL8b++jN9kEbUbv+N693mYAZvc2+7CInGcSNbtXMuPlZdubzNF3dxMI\nAtCd1wEwxuYCmAsAA/TGZh/Rp07XSLbZ0axNooi4nTvFJuWrruL1NaqqxFF1dr4OzcRtF8n41Vf+\n96Oobc3NzXjhhRewYsUKvPHii5jS3o4LjvwJnsyJoaG962iyAPUY3LwN2OVhkmv2gFYY44Xvusv5\n/YyjTa1D7r23c+6MX/8aWLq0w+/w/vvmNnWr+H2g6+jaTxu/HXrHUUuL9ZctmaPv7uAETASymsJq\nA/A
 9AK/q/r8VwK2GY14F8L343wEA+wEwu2snagaQbiY/mcGHXRbN8nLvAxhROgnjpmUc8KUfBVE1\n//jHP+inP/0p9erViwDQxF69qD4UotZIhGIIU5FVmgbUUKygl7cP00lIp9Febpc329hZVh+WTDio\nm0IG6WDb1j73sjJvtYkVnUAyw0DjAn0XgEHocAKfZDjmx+jsBH5K5tqJUgAyiQSTlRFU1q8omjX7\nkUph40b53Pf5+R3y2i73jtSNDZqrrbCQqq6/nk455RQCQMFgkC655BJ6pbqa2g0PuhHFVIQaiuIQ\nMbRSFIeoCDW0EcXenZiyzkozYWWXNxvg5pzSUvEXzU7Lzp8vr6TcfDGSRRambEgUSVUA/H44H8A/\nwW37t8ffKwcwJf53GMAfAewAsBHAYJnrpmIGAPCFSXYDs2S0RWQS1g+UysutrxEK2cuYhgZxXQ8r\n2eF5BiDQfjUAnXn66fTb3/6WampqhJ3VgDBVYjotCSymSszgI38/PjiZGYBV6mNR3mwnWtJOy44d\n67wQjLGamCKjSLoCSNSWKAXg1GeWyMGS01G02UBJZqAqUmaVlXKj/1DI5wjCykpqtbA5tUYiXTWI\n3YOWlvo7gpT5ooiE+IoV9h+KnZb0ewbAWIcHX5GROFEAWVkU3izyTYQxws9PhgzpSONuJD+/ax4i\nsyLxMlF1oprfO3eK8/EA3B/3yCOdw0vdRhDW1NTgoYcewsM33QRm4dnOjcW6hgCKHjQa5Vnn9B0D\neIv11R4wErE+RpQs6oor+Eq8YNB8v4yT0y5E8a67xLG9Zu094QT54/V0p7hphRyymiIVW6IXgumr\n72lmH7czdbfU1nqrsEXkbEZjNuiUmQGUl1vfX8Z829LSQs8//zxddNFFlJeXRwDotoEDqcnqxmYN\ndTrl8Cu0r7ZWrtiCFV7bYXe+2X4nq/j8aIMibYAyATnDLllZMJi4gInKSnEpV5Hg
 1eM2XJ2IywOR\nD6Cw0L1F5YMPPqCbbrqJjj76aAJAffr0oeuvv57effdddzYkWUEkm0xN1tvvVQB6dXLanW/c72cC\ntwxLlpbpOFEAjB+fnhQXF9PmzZsdn+c0y2xVFS9naBWOHInwVatuQ4JF7VmyBFi8mP+azAiHgQMH\n5O6t3ae6GnjhBfMZejTKyzYaU8O8/z4wdmzXlDA9egCvvy7IiGvycLUNDVi1ahVWrFiBTZs2IRAI\n4Ac/+AGuvPJKTJo0CXn6Jb9WKY9FaXi1e4ritauqgLIy8xw3mknHLI+9KPWvzH3TCWN7J03iqZud\npl8W9WU0ypd3J2sNgcIWxtg7RFQsdbCspkjF5mYG4GagZld/W8tX4wa79lRW8mhAq9G3FmTiZLAq\neh7t/mbtaWjg9yot5VtFhc29dA/Xzhi1hMN0OC+PvhcIEAD6z//8T7r//vvpyy+/FDc4ESGAsiGc\n3Wk0K8pCaoeXGYwv8b6KZIFsNQF5malqvw8t3YIxWZkbZNoTi4kVAGCey6u8XCwHzH7vhYVEPXr4\nJPsED1cfCtGWv/3Nfcf5gZNFXHrtmOrFUVZ4EeBeTTjptnJSISRrFYDX76nfA1HZ9tj5IOxklmgR\nqf55Kir8+R0fOHCA1s2eTXU5OeYXCwZ5eKKbKi4LF/JzFy709iG4yY/jdDTrZUTuhFQL8O5UMUmR\nvQog3Waqsu2xc8LKbDK/Q0f9YxBurXV19Oqrr9L06dMpHA7TAoDaRA0KBuVHqOvX8+lWXl7na+Tn\ne4s0MRs1RyLWXneZlbmiaycqKsarAPfjh6GigLoNThRA2iWD84KftX39KFc6ZAj3N5o5l/XtCYeB\ntWu7+kJbWuzj8zVkSsyK+icvj8f4NzYC4fc7HLNUX4+mQACNra24nQif9eyJh886C1Pa28E2bLBO\nNtbczDe7rHAbNgBnn83FkZFYrCMhm5sMfWYJvs4/Hxg0iF/
 XSGMj8PTTwCuvmNeD1b4UW7cC993X\nOTtfIrMJei1Y4scPI1uTpWU6spoiFZvTGYDbmapxJu80gs7KErBhg7eiKnPnys8AZHIYia0i7RQN\nNVNRuIHeDo0yPag5HKb2wkJntnXRCLWhQS77nN92ZuNoVmZaJRtnmwibuDLhKByAbDUBEdnPVO2E\nfUGBM6Ftdb+1a61lm2xkkdOiUqGQvcLqcHa3E9Bu/pyooRgkM8PJaCYrE0NlpVyF+0TY7/SrAO0W\nozkpxpyItvohwJUJJ2twogAyygQEiGeqxpDzSITP4ok6zhflwTeaWWpru5Z+1WbZ48ZZX6egAPj0\nU/tnGTaMp34ws1aYoZmLRNaIkSOBz9Zsxk3n/QOPYSaa0bVqVSsCeBYlmIEn5W4sQmRi2LnT2oQk\new23aDk1du4EnnnG/BjNvOKkGLObttrZG2UKL9uhTDgKEzJOAQDmtS3ManvYFT0xoje3btgAnHee\nnPwSXUeEVkxdVgEYMfULxGIIX3Aejmm+Fi0wr8FYjwLsgk8Ct70d2LaNLyYyCpwhQ/hCIjPbtB4n\nhUGcOm9k7OMiG7yXtgL2ReY1/BDgySz6ougeyE4VUrH5mQrCTVi4lUVAVDBdZsvLM88gbIasudrO\nGtHW1kZvvvkm/b9Ro+hrgCoxnaL42vw5cYgqMd1bZ+Xn8wZEItYmB7tQzXDYe86cwkLxogkZ84rM\nl8eNSSXdUiwkK6xVkVCQzT4AK9wsDDX7TYrygjnZCgvlZUVNDQ+NP/FEcdI6M5l0//1f0OLFi2ng\nwIEEgJaEQtQGUAwhKkKN+XO69QEUFPDOueoq+eRpRudqbi5RTg7Rqafyh5bJhkdkb6cX2b3t7OMi\nJRGJdJRHcyow02mBlfIRZAxKAZjgdAagT6qo/y3I+i1lFYqTcHOn1w8EviYgRIwxGjduHFVWVlKz\nzrMsrKZldsEePbjmMluWrF8951Sw+b
 EOwEv5RiL7VYCJEJDpsnAl3WYiCk84UQAZ6QMwQ7Onm8EY\nN71qJtj2dmD6dCAUAvr04enTNXPrK6+4s/ubYRe776QmOYfiWz2AFhxzzBzMm7cQM2fORP/+/fkF\njz32m6NHYjM+w3GoxlTswmAMxi6U4FmEEfcmh8Pcs6x3OI4YYW+HdhK3HosBU6aYV7x3sg5g61Z7\nX4KGWcfb2ccT4UT1c+GKF0RObpkFJopuS9YoAFEgxZo1wO7dwPr1wMqVXCEsX24eaCHrt5Shrg54\n4AH+t5kscRJ8AgC5aEQ/9hJO+N7nuHdMLU4OnQo2aBDXYhYXzEejdbRPTg6waFFnDQjYCwMngk3m\nIe2E0KZNfGGWLLJeeCN+O1FFoxKnzmQveF1opui2ZI0CAMSDuFiM/xbtFndOmsRnCDKEw3zA/e9/\nA21t5sds2sQz7ZoFfjgJPgGAHojh49Ac5P/1ELAlHj+qjypxesGcHC78ZYSePvqmf38gN9f8OGNU\nkEybREJImyFYVBYzJRQC3n3XPDLJ6h5el4Wb4Ud4px+ky0xEkXxkbUWp2JJVEIZIzmytmYFFBVyM\n5tMDB+SdxkZ/otis3U4BNBNDG0Xxtdh2rzVGlA3Oyg6tNchp6tEePfir9p5VVJCoor2MQ9RLeJeM\nHT8ZztFEpMN2glopnFEgWU5gAPcA2ArgPQDVAIosjvsEwPsAtjhpnN8KQBTlZuePW7TI+jcSCpn7\nRjUZUVbmTi5t2EB0xBGtpscUooYqMJOW4HaqxHT7qJ2CAp5bwi73tH7Lz+cCWyT87ByIFRW886y0\nYGGh/SpbkRCyC+/S59J2ev1sco6qKKCMwYmM9WoCWgvgViJqZYz9CsCtAP7L4thziGi/x/u5xm69\njd0seP9+a1N1Xh635QeD5v7B0aOBP/xB3vqiteGccw6jtXUSwliDAAKoRwEKUI8AWvEaJmAkHFRL\nq68HVqzgGeZka
 Wzk4s7YML1NzM6BGAwCQ4dyc5IZbW3Az38OLF3KHc76VW/hcIeZxMocIvrg9OXP\nqquB5583z65n5WPIJueoWimclXhSAET0mu7fvwEo9dacxGAWTWOUZXb+uF69xH6yPXuABQvM94uu\nLaKtjaGk5Hrc951K/GXRP7Cr6diukTpOMIYvhcPAgw9yD/g993Bh39TEBafm6DCzreuFn4wDkcj6\nmLo67nVfswaYOJEL6+ZmrlVzcrjQFpVptPvgpk3jz7lzJ8/0adUGMx9DtjlH1UrhrMNPJ/BsAKst\n9hGA1xhjBGAZET3q431tkR3Iifxx27e795PpfX0tLU78sAX49rcvwsCfNmLg3X2BJpN4UMY6j9Kd\nEAjwxpeXA7fe2nn0t20bL1hshl74yToQrY4BuMA3hoK2tPDtggvEIaCyjtT+/cV90a9f1/eUc1SR\n6djZiACsA/CByXah7pjbwX0AzOIax8VfjwLwLoDRgvvNBbAZwOYBAwZ4soVpNv+xY63Nv8b1Nlb+\nOD/8ZNq158xpoVCohXJz6wloI6usnJ18n1Y22hUr+Kub1Wl2mTplFnPJdIxdxZtIpKMWp7ATJDrX\nypFaUSHuC7PcHMo5quiGIJkrgQHMAvBXABHJ4+8AcJPMsV6cwE7St8+fL5f+xCiDtcwHZWX257a3\nt9PGjRtp/vz51LNnTwLCdOSRP6Gzznqd8vPb5GSMlZBraOAP4VQJiISrE+En40AU1b0UtduvFbFu\nV90q56iim5E0BQBgIoCPAPQRHFMAoIfu778AmChzfbcKwGn6dq0GgMxvW5PBZWX2ATJERPv27aN7\n7rmHTjrpJAJA4XCYfvSjH9HatWuptbWViHySMaJRtpMCB3qcNMxuBG4ngK2UgF85cbzk3Ul1mKZC\n4YBkKoAdAHaDh3duAfBI/P1jAbwU/3tw3OzzLoAPAdwue323CsBr5k87ucgVjEUxlSKigwcb6e
 mn\nn6bJkydTbm4uAaDvf//79Oijj9LBgwctr+lJxmzcaP7Q0WiHmciNhvFL+NkJYNnkcW5R5hxFlpBU\nE1AiN7cKwGklLdGA0GztQGX5DstUynl5MSoouJoA0HHHHUe33norbd261dVzSNPQIBausVjqR7F2\nAthpHU43KHOOIgtwogAyLhWE07QwZmhBLuZrBwiXNvwZ9Zhlem5LSx6GDTsP99xzEc477zzkWqVE\n8JPVq60jbOrqgFWrgFmzUhviZxet4zQO3Zh6AuDhrKJUDSrWXaHoBOMKIz0pLi6mzZvlFztpyS7l\ns2eaE4kAv/0tcP315teKoA45INShR5d90VAzli0PJlfWTp0KPPec9f7SUuCPf+z6fqJy3IjQ7ulF\nABs1s/47HI12ViqiNiTzuRWKJMEYe4eIimWOzagZgNPsmVbEYjwE3epaDO1oh/nK1gBr65zEMdHC\nZtMm4MUX3Z0nWhqdqHZ7XWxklyNbVBAZkC/BqFBkA7K2olRsTn0AflT9Anj6mNJSQdAKWqkM/8+k\nmEotbSx/uaNBms1Zi3EPBrmzc8OGro13U45PNtzJGONul+MmGfZ4t8h6+M0ie7Ipt48ia0G2+gCG\nDHoJ+8kAABLESURBVOHmG6fF3o00NhI++2wfcnJ6oq0tv8v+AjRgNDbgftzQuZhK4RsI3/wJP8hs\npNrczLfRo3nxgVGj+PtuR6UyU54ePXg6BNnzWlqACRPs82KnCtmU1mapGrIpt49CIYFFhq7uSUlJ\nZ3Owe5rxl7/civZ283w7gR75KCl8A/nRAGawVVgQ/R/MKHoZ4bXPdwjH6mrrxGtEXMg2NnZWFHV1\nfF9dHf9/9GiewK2x0fw6dsIwHAZef915xS4rIdnQANx4o3V7koGWnsEOs1QN2ZbbR6GwIaMUQDgM\nXH65+Jhg0P46ubmEZ565FP/3f1EUFXG/ImP8tagIeO31AML7/gUsW8bz6
 CxbxkfGTqq5aCPO1aut\nBWpjI3DNNUDfvnyWYEQkDEMh4OGHzWcQovO0ZGxmNDcDjz1m3Z5kUFLCnbx2mFXUEj23yu2jyEZk\nbUWp2NysAxCZiAsKeMaEBQtaKRRqsbDvt9OGha9+Yw92HT5vVz2eMb6cWDY/v5mN2u3iJtF52vJm\nN+1JFsZ4fqPt38pfoRaDKbIAOPABZFQYKMAHzX37mgeJHHFEG666aiGefLICn3/eD4ytRSAQRktL\nCEE0I4BWvIoJGBV91z6UUKYhvXpZlyrUUi7LljKMRvlMw2ijNvMfyLTd6rznn+cZOO1iaa3akyz0\n4aRaJs89e+xDS932l0LRTcjaMFDAbL0RIRhsQWtrI77++lw89NAWTJ48GbNmzcI550TwYjWw65q7\nMLjxo448+9qaKr3TMxbj5hot5HLy5I5c8xrG0Mk1a4Bx48wdE+3t3K4ki5WN2u3iJtF5Wgc2NFib\ng5JhMxeForoNJ1WLwRSKDmSnCqnY3KaCaG1tpeeee5W++90HKTd3MQHTacSIYrr//vvpiy++6Hyw\nbDHgHj3M92umBqs0A8uWcbNKMNj5/bIyZzGrfiVFk8Uuw2ii26PSNigUrkA25wI6fPgw9evXjwBQ\nr1696Kc//Sn9/e9/p/b2dvMTvBQDBngGztpasW25trarI8FpxrpU2KhTZTNX8foKhWucKICMMwFF\no1FcccUVOO200zB58mSEQiHxCTLFgEVhj42NvBakKL785Ze7mitk60QGg3xxg6gubqKQrbblNype\nX6FIChmnAADgzjvv7PyGyJZsV1O2sFCsAJqagI0brZOxWdnKNeE6bhxvnyj00ihoE5GmweqaqbCZ\nq3h9hSIpZKQC6MSmTVzINjZyYR0KAfPnA2vXcuEmGuU+8AA/VkQwCLz3nvV+u/hymZq+X3/d4ZB+\n/33/c9nYrUSWcbj6qZRULV6FIilkXBhoJ2Ix4Kij
 zAVJNAp89VWHkDJmqZw0ib/ahUPm5wM5OdYj\n1kgEqKkxH8U7SV0ajQIPPWSdorSoyF2aBlE7ZK/pd2ilKJbX7XMqFFmCkzDQjFoJ3AWZPPka2ih3\nwQL++vLL9nl2olFg5kxxLP/ll/MRflUVsGQJf21sdJ66tL6eh6Da2cadImNvFyFKZTF+vLu0Edqs\nzHQZdgp8IQpFhpLZCsAuTbJov10qh6lT+Qxi9GhxeoHjjuMj7LIyYPFi/tq3L08G5yRrnXYPq3Pq\n6vg1neLV3u5VgVih+R5E6TYUCoUnMlsBeEGUNyYa5UVWwmFxbpq8PF6ezGx0vHIlNw/JEgjwxWei\nRGjLl4uTx5nhNT9OIh22xlmZGvkrFL6S2Qpg8mT3+0WCXZ9oTGSuuOEGoK3N/Bo5OXKpS/PzO0wf\n06bxFcRWtLSIk8eZIXrO1lYehSRSKCrBmkLRbfGkABhjdzDG9jLGtsS38y2Om8gY28YY28EYu8XL\nPR1x4YXWo0azPPkAt2lXVQH33MMFeGGhvR3aylwBiEfHl1/Oryca1TMG/OtfHRFLdulOGxud2d+N\nCkxPUxNw7bVihSKrKJ2ifQ56v4lCofAX2RVjZhuAOwDcZHNMLoCdAAYDCAJ4F8CJMtd3mwqCiDpS\nCUQinVeSBoPWKQWs0g+Ul7tIB0pyaSacplyorOyoMOZn6oiGBl45zCo7qWgFrt9pG1QaCIXCNUiz\nlcBnANhBRLsAgDG2CsCFAD5K2B1FdWMDAT6iLiqyP0eLIFq61FnooRZSunWrtclGGx2Hw8Axx1gX\njzHa0WVXENfVObO/5+fzNQ0ic5DVClw/F4uJPod0qEimUGQQfvgAfsIYe48xtpwx1tNk/3EAduv+\n3xN/zxTG2FzG2GbG2OavvvrKeWtiMeCmm6xDM3NygJde6vr+vfdax+Q7iWbZtKkj6ufOO/n4mTHu\n8LUyIzmxo+tNNnbVbbQ0ybJ
 4cej65bBNVFSRQqHogq0CYIytY4x9YLJdCOBhAEMAnApgH4D7vDaI\niB4lomIiKu7Tp4+zkzXh+9hjztIYx2LAL35hfV3ZaBazmPhYrMPZu2iReTijUzu6NuKeNcu+TU5I\nB4euSgOhUCQNWxMQEZ0ncyHG2O8AvGCyay+A/rr/+8Xf8xeR2UePmSCrrhZH5IRCcsJPNHrNyQFO\nOMHchOIm6Vp+Ph/hW6WSYIwXSHGCXV4ktw5dJ6g0EApF0vAaBdRX9+9UAB+YHLYJwPGMsUGMsSCA\naQDWeLmvKbIra80E2c6dPOJFhIzw27lTvPJYNHp1s/DJ7xF7OqzATVRUkUKh6IJXJ/CvGWOnAiAA\nnwAoAwDG2LEAHiOi84molTH2EwCvgkcELSeiDz3etyt2K3dFaZWHDOGCzkp433abnPDr31+8384m\n77TKVSJG7KmumJWqFNQKRRbiSQEQkWlQOhF9BuB83f8vATDxvPqIyHQQDAJz5vBVuWYCRCRICwuB\nm2/2t62y2GXYTJSwdFtu0S9SrYQUiiwhc9JBi4R4JGIt/AH/BOnu3eL0zk5s8nYpmjUyVVimWgkp\nFFlA5igAr0LcD0EqmoUAcqkfAOex8EpYKhQKF2RePQBjXv9kjoYbG/mirkOHzPfL5rKvquLrCKzq\nGCxbpgS+QqEwxUk9gMyZAWikcjQcDgM33sjj/c2QrWerYuEVCkUSyDwFkAz0qR5qaoDevYGhQzui\nbqz8ALLCW8XCKxSKJKAUgFM052xTE1cEGpEId9LecIN34Z0OC7IUCkXGk9n1APxG75zVC3+A5x46\neJBHG3ldyJQOC7IUCkXGk/kzAH0svbZQa/du87h6O2RWG7e1AT//Oc8g6iWkNFPDOxUKRdqQ2QpA\nH0uvN8kwZh1XL8JutTHA9zPmj/BW4Z0KhSKBZK4CECWH02rzAs5yzNvF+QMddn4lvBUKRZqTuT4A\n2eRwTn
 LMixKVaSgnrUKh6CZkrgKQMdcAzuLq9c7Z/PzO+yIR5aRVKBTdisw1AcmYawDncfV65+y2\nbcD+/UCfPjzXv3LSKhSKbkTmpYLQaGwE+va1LxAjm55BFrsMngqFQpFAsjsVhF4A33ADj8tvazOP\nAvI7x7xsBk+FQqFIAzJLAZgJ4ECAx+Uz1lGQZc8e/+PqnWbwVCgUihSTOQpAJICXLk28ABZFHckm\ngVMoFIokkjlRQDICOJGoDJ4KhaKbkTkzgFQL4EzO4Kkc2wpFRuJJATDGVgMYGv+3CMBBIjrV5LhP\nABwG0AagVdZD7YhUC+DukMHTjSBXjm2FImPxLQyUMXYfgENEVG6y7xMAxUS038k1HYWBisI+/Q71\ntMLKCZ0OwtJN22Ix4NhjU9unCoXCEUkPA2WMMQCXABjrx/VcYVcTmIiXWkykGSNdM3i6jVBSjm2F\nIqPxywdwFoAviGi7xX4C8BpjjAAsI6JHfbpvZ6wE8Pvv85FsMswY6ZgEzq0gT7VfRaFQJBRbBcAY\nWwfgGJNdtxPRn+J/TwfwpOAyo4hoL2PsKABrGWNbiWi9xf3mApgLAAMGDLBrXleMAjhd4vNT6Uh1\nK8hT7VdRKBQJxVYBENF5ov2MsQCAEgCnC66xN/76JWOsGsAZAEwVQHx28CjAfQB27bMlHcwYqXak\nuhXk3cGxrVAoXOPHOoDzAGwloj1mOxljBYyxHtrfAMYD+MCH+8qRajOGfgZSV9dRi+DgQf5+Y2Ni\n7w+I01iLBLkqTalQZDR++ACmwWD+YYwdC+AxIjofwNEAqrmfGAEAVUT0ig/3lSPVZox0mIHYOchF\ngjxdHdsKhcIznhUAEc0yee8zAOfH/94F4BSv93FNqs0YqZ6BaHgR5Ono2FYoFJ7JnJXAVngZ/fpB\nqmcgepQgVygUOjK3HoARLQon2WaMdFigplAosobsrgdgRapGv6megSgUCoUF2aMAUol
 ypCoUijRE\nKYBkoezvCoUizcicegAKhUKhcIRSAAqFQpGlKAWgUCgUWYpSAAqFQpGlpPU6AMbYVwD+7fL03gAc\nFaBJEqpdzlDtcoZqlzMysV3/QUR9ZA5MawXgBcbY5oSUnvSIapczVLucodrljGxvlzIBKRQKRZai\nFIBCoVBkKZmsABJTdtI7ql3OUO1yhmqXM7K6XRnrA1AoFAqFmEyeASgUCoVCQLdWAIyxixljHzLG\n2hljlh5zxthExtg2xtgOxtgtuvcHMcbejr+/mjEW9KldRzLG1jLGtsdfe5occw5jbItua2SM/TC+\nbwVj7F+6facmq13x49p0916jez+V/XUqY+yv8c/7PcbYpbp9vvaX1fdFtz8Uf/4d8f4YqNt3a/z9\nbYyxCV7a4aJdNzDGPor3z+uMsf/Q7TP9TJPUrlmMsa9095+j23dF/HPfzhi7Isntul/Xpn8yxg7q\n9iWkvxhjyxljXzLGTMviMs6D8Ta/xxg7TbfP/74iom67ARgOYCiAtwAUWxyTC2AngMEAggDeBXBi\nfN9TAKbF/34EwDU+tevXAG6J/30LgF/ZHH8kgFoAkfj/KwCUJqC/pNoFoM7i/ZT1F4ATABwf//tY\nAPsAFPndX6Lvi+6Y+QAeif89DcDq+N8nxo8PARgUv05uEtt1ju47dI3WLtFnmqR2zQLwG5NzjwSw\nK/7aM/53z2S1y3D8tQCWJ6G/RgM4DcAHFvvPB/AyAAbguwDeTmRfdesZABF9TETbbA47A8AOItpF\nRM0AVgG4kDHGAIwF8HT8uMcB/NCnpl0Yv57sdUsBvExEDT7d3wqn7fqGVPcXEf2TiLbH//4MwJcA\npBa7OMT0+yJo79MAzo33z4UAVhFRExH9C8CO+PWS0i4ielP3HfobgH4+3dtTuwRMALCWiGqJ6ACA\ntQAmpqhd02GobZ4IiGg9+GDPigsBPEGcvwEoYoz1RYL6qlsrAE
 mOA7Bb9/+e+Hu9ABwkolbD+35w\nNBHti//9OYCjbY6fhq5fvrviU8D7GWOhJLcrzBjbzBj7m2aWQhr1F2PsDPBR3U7d2371l9X3xfSY\neH8cAu8fmXMT2S49V4GPJDXMPtNktuui+OfzNGOsv8NzE9kuxE1lgwC8oXs7Uf1lh1W7E9JXaV8P\ngDG2DsAxJrtuJ6I/Jbs9GqJ26f8hImKMWYZaxbX7yQBe1b19K7ggDIKHg/0XgPIktus/iGgvY2ww\ngDcYY++DCznX+NxfKwFcQUTt8bdd91cmwhi7DEAxgLN1b3f5TIlop/kVfOd5AE8SURNjrAx89jQ2\nSfeWYRqAp4moTfdeKvsraaS9AiCi8zxeYi+A/rr/+8XfqwGfXgXiozjtfc/tYox9wRjrS0T74gLr\nS8GlLgFQTUQtumtro+EmxlgFgJuS2S4i2ht/3cUYewvAtwE8gxT3F2PsCAAvgiv/v+mu7bq/TLD6\nvpgds4cxFgBQCP59kjk3ke0CY+w8cKV6NhE1ae9bfKZ+CDTbdhFRje7fx8B9Ptq5YwznvuVDm6Ta\npWMagB/r30hgf9lh1e6E9FU2mIA2ATie8QiWIPiHvYa4Z+VNcPs7AFwBwK8ZxZr49WSu28X2GBeC\nmt39hwBMIwYS0S7GWE/NhMIY6w3gTAAfpbq/4p9dNbh99GnDPj/7y/T7ImhvKYA34v2zBsA0xqOE\nBgE4HsBGD21x1C7G2LcBLAMwhYi+1L1v+pkmsV19df9OAfBx/O9XAYyPt68ngPHoPBNOaLvibRsG\n7lT9q+69RPaXHWsAzIxHA30XwKH4ACcxfeWnhzvZG4Cp4LawJgBfAHg1/v6xAF7SHXc+gH+Ca/Db\nde8PBv+B7gDwRwAhn9rVC8DrALYDWAfgyPj7xQAe0x03EFyz5xjOfwPA++CC7A8AoslqF4Dvx+/9\nbvz1qnToLwCXAWgBsEW3nZqI/jL7voCbl
 KbE/w7Hn39HvD8G6869PX7eNgCTfP6+27VrXfx3oPXP\nGrvPNEntuhvAh/H7vwlgmO7c2fF+3AHgymS2K/7/HQB+aTgvYf0FPtjbF/8u7wH31cwDMC++nwH4\nbbzN70MX3ZiIvlIrgRUKhSJLyQYTkEKhUChMUApAoVAoshSlABQKhSJLUQpAoVAoshSlABQKhSJL\nUQpAoVAoshSlABQKhSJLUQpAoVAospT/D6/mlctKc+nbAAAAAElFTkSuQmCC\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f68af50c890>"
+       "<matplotlib.figure.Figure at 0x7f986a5ac198>"
       ]
      },
      "metadata": {},
@@ -154,9 +153,7 @@
   {
    "cell_type": "code",
    "execution_count": 6,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -171,7 +168,7 @@
     "layer.engine = 'singacpp'\n",
     "dense = layer.Dense('dense', 2, input_sample_shape=(2,))\n",
     "p = dense.param_values()\n",
-    "print p[0].shape, p[1].shape\n",
+    "print(p[0].shape, p[1].shape)\n",
     "\n",
     "# init parameters\n",
     "p[0].gaussian(0, 0.1) # weight matrix\n",
@@ -205,31 +202,29 @@
   {
    "cell_type": "code",
    "execution_count": 7,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "training loss =  0.705488\n",
-      "training loss =  0.479273\n",
-      "training loss =  0.414510\n",
-      "training loss =  0.370120\n",
-      "training loss =  0.337781\n",
-      "training loss =  0.313082\n",
-      "training loss =  0.293514\n",
-      "training loss =  0.277555\n",
-      "training loss =  0.264237\n",
-      "training loss =  0.252912\n"
+      "training loss =  0.704490\n",
+      "training loss =  0.483168\n",
+      "training loss =  0.411447\n",
+      "training loss =  0.362376\n",
+      "training loss =  0.326843\n",
+      "training loss =  0.299900\n",
+      "training loss =  0.278710\n",
+      "training loss =  0.261552\n",
+      "training loss =  0.247332\n",
+      "training loss =  0.235318\n"
      ]
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAADSCAYAAAChKgyOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXmYFdWZuN/T6+3u23YnkhgQiIKKUWIwgD+jBlAjimvo\nYSaik+jECIqauI9GUdNMzAIuiYkZGCNmwdGMkXGJUTSOgBkTQMc1ggbRAC6End637/fHuUVX367l\n1L11l4bzPk89d6ntVN265zvnW5WIYLFYLBaLm5JCN8BisVgsxYcVDhaLxWLphxUOFovFYumHFQ4W\ni8Vi6YcVDhaLxWLphxUOFovFYumHFQ4WS0wopQ5QSolSqqzQbbFYssUKB4ulQCjND5RSW1LLD5RS\nqtDtslgA7AjHYikcM4AvA58DBHgaWAf8eyEbZbGAnTlY9mCUUkOUUr9VSv1dKbVOKfVN17pblFIP\nKaUeVErtUkq9pJT6nGv9Z5RSzymltiul3lBKnelaV6WUuk0p9Z5SaodS6nmlVJXr1Ocqpf6mlNqs\nlLohoInnAbeJyAYR2QjMA86P7w5YLJljhYNlj0QpVQI8BrwC7A+cCFyulDrZtdlZwH8BHwfuB/5b\nKVWulCpP7bsE+CRwGbBIKTUqtd88YCxwTGrfa4Ee13GPA0alznmTUuozPs08PNU+h1dS31ksBccK\nB8ueynjgEyLSKCIdIvIO8B/A2a5tXhSRh0SkE7gdSABHp5Yk8P3Uvs8CjwPTU0Ln68C3RGSjiHSL\nyP+KSLvruN8RkVYReQXd4X8Ob5LADtfnnUDS2h0sxYC1OVj2VD4NDFFKbXd9Vwosd31e77wRkR6l\n1AZgiLNORNyzgffQM5BBaCGyNuDcH7ret6CFgBdNwD6uz3VAk9hsmJYiwAoHy57KemCdiBwcsM0w\n501qRjAUeN9Zp5QqcQmI4cBbwGagDRhJX5VQJryBn
 lWsSH3+XOo7i6XgWLWSZU9lBbBLKfWvKQNy\nqVJqtFJqvGubsUqphlRcwuVAO/An4M/oEf+1KRvEJOAM4IGUsLgXuD1l8C5VSn1BKVWZQRt/CVyp\nlNpfKbU/cBVwX6YXbLHEiRUOlj0SEekGTgfGoN1DNwP3oFU3Do8AXwG2AV8FGkSkU0Q60MJgSmq/\nu4Gvicjq1H5XA68BK4GtwA/I7L80H234fi21PJ76zmIpOMqqNy17I0qpW4CDROSfC90Wi6UYsTMH\ni8VisfTDCgeLxWKx9MOqlSwWi8XSDztzsFgsFks/rHCwWCwWSz+KOghu0KBBcsABBxS6GRaLxTJg\nePHFFzeLyCeyPU5RC4cDDjiAVatWFboZFovFMmBQSr0Xx3GsWslisVgs/bDCwWKxWCz9KGq1ksVi\nsezNtLbC4sWwdi2MHAkNDZBI5OfcxsJBKXUvOlfNJhEZnfru48CDwAHAu8A/icg2j31PAX6ETpl8\nj4h8P9MGd3Z2smHDBtra2jI9xF5PIpFg6NChlJeXF7opFovFh5UrYfJk6OqC5maoqYFLLoElS2D8\n+PD9s8U4CE4pNQGdf/6XLuHwQ2CriHxfKXUd8DER+de0/UrRqY5PAjagk5VNF5G/hJ1z3Lhxkm6Q\nXrduHbW1tey7777YmijRERG2bNnCrl27OPDAAwvdHItlr8drdiACQ4bA9u39t6+vhw8+8J9BKKVe\nFJFx2bbL2OYgIsvQGSjdnAX8IvX+F+hi6ekcBfxVRN5JZbt8ILVfRrS1tVnBkAVKKfbdd18787JY\nioCVK7UQmDkTbr5Zvw4eDPPm6RmDF11d8PDDuW9btjaH/UTkg9T7D4H9PLbZH1fFLfTs4f/5HVAp\nNQOYATB8+HC/bTJpqyWFvX8WS+FpbdVqI/fsoKlJv956K7S3e+/X3AzvvJP79sXmrZQqbZh1oiYR\nWSAi40Rk3Cc+kXUcR+xs376d
 u+++O6N977vvPt5///3dnw844AA2b94cuM9zzz3H6aefDsCjjz7K\n97+fsbnGYrEUEYsX+88ORKDSp3xUTQ2MGJG7djlkKxw+UkoNBki9bvLYZiOucozoUowbszxvwQgS\nDl1+v3SKdOEQlTPPPJPrrrsu4/0tFkvxsHatngV40d4O3d3e68rKtF0i12QrHB4Fzku9Pw9dWSud\nlcDBSqkDlVIVwNmp/QYk1113HWvXrmXMmDFcc801PPfcc3zxi1/kzDPP5LDDDuPdd99l9OjRu7ef\nN28et9xyCw899BCrVq3i3HPPZcyYMbS2tgJw11138fnPf57PfvazrF692u+0gBYul156KQDnn38+\n3/zmNznmmGMYMWIEDz300O7t5s6dy/jx4zniiCO4+eabc3AXLBZLtowcqWcBfqRrfysqtDF6yZL8\nuLNGcWX9T2ASMEgptQG4Gfg+8Bul1AXAe8A/pbYdgnZZPVVEupRSlwJPoV1Z7xWRWIqoX3755bz8\n8stxHGo3Y8aM4c477/Rd//3vf5/XX39993mfe+45XnrpJV5//XUOPPBA3n33Xc/9pk2bxk9+8hPm\nzZvHuHG9jgSDBg3ipZde4u6772bevHncc889xm394IMPeP7551m9ejVnnnkm06ZNY8mSJbz99tus\nWLECEeHMM89k2bJlTJgwwfi4Fosl9zQ0aNdUPzo6+n+uqsptm9wYCwcRme6z6kSPbd8HTnV9fgJ4\nInLrBghHHXVUxm6hDan54dixY3k4ogvCl7/8ZUpKSjjssMP46KOPAFiyZAlLlizhyCOPBKCpqYm3\n337bCgeLpchIJPQswB3LUFHhb4gG2LFDbx/kyhoXAzpCOmiEn09qXHPDsrIyenp6dn8OcxmtTFmd\nSktLQ20WfvuCjl9wXq+//npmzpwZ6ViWgU8ho2ktmTF+PLz/vv7d3nkHXnkFfvtbbZD2w3FlPeec\n3LbN5la
 KSG1tLbt27fJdv99++7Fp0ya2bNlCe3s7jz/+uPG+cXDyySdz77330pTyidu4cSObNnn5\nCVj2JPz85VeuLHTLLGFUVemO/sYbYerUYDsE5M+VdUDPHArBvvvuy7HHHsvo0aOZMmUKp512Wp/1\n5eXl3HTTTRx11FHsv//+HHroobvXnX/++Vx00UVUVVXxwgsv5KR9kydP5s033+QLX/gCAMlkkl//\n+td88pOfzMn5LIUnyF8+XyoISzyE2SEgf66sRV1D2it9xptvvslnPvOZArVoz8Hexz2H++/XMwVH\nILhJJmH+/NyrICzxsXIlnHSSti94UXTpMywWS3ES5C+fLxXEnk5rqxbCc+bo11xmnxk/Xnf+jY1a\nACQS2q01mSxSV1aLxVKcOP7yXjOHfKkg9mQKkR21qgpmz4arr+41Vo8YUaQpuy0WS3ESpKfOVzTt\nnkqh7TmOsboQDEi1UjHbSQYC9v7tWTj+8vX1WvVQCBXEnkpQ/qN8ZUctFANu5pBIJNiyZYtN250h\nTj2HhO0x9ijS/eXzrYIYCPjFgYR976Wug+j2nIEWhzLgvJVsJbjssZXgLHsaYR2vl92grAzuvBMu\nv9z/+7Y2f+Oz4wk2dWp4p++c3zmeY2jOhd0iLm+lASccLBaLxY1fx+90vK2t/lXVlPKORvb73k19\nPTz2GJxxhv+5QZ9/v/3AK/61thY2bYp3BlE0rqxKqVFKqZddy06l1OVp20xSSu1wbXNTtue1WCwW\nt8G4qUl36E1N+rMzUg+rmxDle9B1Furr4dFHtWAIOjfAgw96CwbQ3z/wgPn15pOshYOIrBGRMSIy\nBhgLtACLPTZd7mwnIo3ZntdisVhMDMZBcSCZcMYZ2ktp/XozY/Xvfhd8vLD1hSJug/SJwFoReS/m\n41osFks/28Lq1eEBgEFxIFFJJrWNIZEwDz6MmE+zaIhbOJwN/KfPumOUUq+iq8BdHVdN
 B4vFklvy\n6WUTdC4v20JPT69nUTpOAGBQHEhUm4M7bsQk+HDlSnjqqeBrTkvPVjyISCwLUAFsBvbzWLcPkEy9\nPxV4O+A4M4BVwKrhw4eLxWIpHCtWiNTXiySTIkrp1/p6/b2blhaRRYtEGhv1a2trfOdatkxk4UKR\nREJEd9lmS21tbzv8jn3ffdG+d193a6v+zuvc9fUiW7f6r3eWZDKzexUEsEpi6NNj81ZSSp0FXCIi\nkw22fRcYJyKbg7az3koWS+EI8vJxJ38L8xbK9lxKQXl5/8poYSST8Pe/9848nFlJehxI1O/dBF37\n22/7J0QEHf28dGnxurLGqVaajo9KSSn1KeAjERGl1FFoQ/iWGM9tsVhixsTYO3VqPOklwjyKogoG\nB6coTpC6yi9FhUnqivHj9TFnz9b2j0MPhe9+VwvPJ58MNoRfc423YCiWYLlYhINSqgY4CZjp+u4i\nABH5d2AacLFSqgtoBc6WuKYsFoslJ5gYXE0EiEluoLg9itxtzGXiPPexm5rgj3+Ee++Fb38bhg3z\nt0kkkzBqVPDxvNqaT8ERi3AQkWZg37Tv/t31/ifAT+I4l8ViyQ8mBte40oXH6VHkbuPQoblLnOeV\nlM+p/3zTTVBX57+vY9h2d/bDhumobHcdB3dbnYA7d5R1LrPDDsjEexaLJfc0NOhOzAunc3M6dS+i\npAsPOpcfiURvskG/NkLuEucFzZpAd/JKaSHhlRDxtdf6lna9+GL/Aj+dnboA0PbtvcF1bW3684kn\n5qa+hBUOFksOyWeRmLgxyfZqIkCyOZdfbs1EAn72Mz3yf/ZZ/zauX5+7QkgmqjARnadp/nxdvGf+\nfN3m0aP7R3YHPRvNzf7rcxVlPeCyslosA4VCFImJk9ZW7XFz2WWwZQsMGqT15G49dyKh00iccoq+\nzo4OfZ3l5dHThXsZdxsaYNq0YE+ooIy0b7+du0JIJqqw5mbYsAF
 uvLFXhTR3Lnz4oZ4NmFJWFjxL\n+dWv4PzzzY9ngk28Z7HkAFM30GLF1D013SBbUaG3e+opOO64eM756KN6BpBJKvK2Nhg8ON7fwenk\n16yBefOgpcV/Wydz68EH9722qK655eXBwqS8HHbudEqKFp8rq8ViSRGXF08hMK1+5rVdR4denPxD\nfh1vutfNlCn+5zzzzL7ndPIlmXjrOOoqP0EXVTCkC7CqquDty8pg0iQtHNxCJEwwVFb2zsLKyvTs\nbc4c/+1LSuJ/pqxwsFhyQFxePIXAVLBlKgD90mD44RwrffRtqqaLqxCSlzB0OvxEQtsNlNIeS+66\nEOmCIYz6erjjDq2OctoK8L3v+d/vjo74nykrHCyWHGDiBlqsmAq2TARg0KzEj+ZmrcK55JLMXVLj\nqMUcJAzLyuCuu7RazRFAU6bo1zDB4ORxcttqRo/unVk9/LC+B0E2h5oa+NjHtvHAAyGJnCJghYPF\nkgOCkr1F8eIpBKaCLWy7oUO1h5ZbBRTm/ulFTQ1s3uy/X1sbfPWrOlo7l0FhYcLQMTw73H+/2bU6\nZt/mZliwQL8fMqR3hlRdHe4V1dKyg0svHQy0h5/QECscLJYs8ItYjVvXnU9MBVtYttPLL4fu7r4q\noK98JXokdFmZ9pTy26+tDR56SKerMFEzef1mIuGRx1Fng5lEfc+cqavD7dzZ+13wMQRo59hjv8NZ\nZ32XiRMnMj4uV7g4svflahk7dmw2yQktlpxikrHUyVY6Z07m2UoLgWk2Vr/tkknvLKTV1f7rnKWq\nqv85Fy0K38+dEdXvPnu1t7ZWv4Zd69atuv0m52xpEZk1S6SiIlomWRApK4uyfY9MmtTdp53ElJXV\nzhwslgww9eiJQ9ddCEyNuF7bdXRo7xovurvDazMrpWMd3DEVBx0UbLR2k24Md2YKq1fDbbf1tQF4\nzQK8fkfHiJ7e9upqbWdwZoOtrdq99dZbdX
 ujJwwUuroE8/hkxWGH+UQKZokVDhZLBgxkV1VTTAVb\n+nZz5virQtrbdWdaWdmbhyidkhItGJxj+nXMfriN4elxGFEIyjzrZt067WHknMtvO9BxD9rdVwC/\nTr0LXR7HjNmzjTeNRCzpM5RS7yqlXlNKvayU6he1pjQ/Vkr9VSn1qlLq83Gc12LJFWFpLwayq2qu\nCcq3BLpz9EuLAX3vn3uG5lXtzQtH/+/eN5OEfiaZZ0tK4IknvGeS6ZSW9jBmzCuceOLX0bYCbxKJ\n8kjtvPvuSJsbE2dupeNFZIx4R+ZNAQ5OLTOAn8V4XoslVlau7JsQbeZMHWW7cmXvNnElnIubMKGW\nj1xPpkn0Kiu9v3ffv0y8mxyjeSb7erUj29TlDt3diueff4w33/wfjj3252gB4SxaYN53n+K886Kp\niebMgeefj7SLGXEYLoB3gUEB6+cD012f1wCDw45rDdKWfNPSElz60TE6hpWILIThOcyIbGpkjqst\nQWU9lfJfr5TI8uX6OI2N+rOpgbauTpcVXbRI5IQTohuDvX7HIGN4MqnX33JLlyjVE2o8Pu64lt33\naMsWbbQ+8UT9um2b/n7RIpHS0mhtrarSpVQbG0Vg0DsSR78ey0FgHfAy8CIww2P948Bxrs9/QJcJ\n9TqWrSFtKRgmHYFDnJ1ttjWYw4RaUD3jTISZSXuD6j4nkyKzZ/t3/CYdc/qSSIhcf732KMrESyh9\nqanR1zd7tr+XUiLRIl/60ulSWTlDoCX0mJMmhd/b1lb/84Vdv76fR3ZLEQmH/VOvnwReASakrTcW\nDu7Fzhws+SZopKqUdkl1E4erahxCJkyozZplLvS8cAuDxsb+7a2uFpk5s+89CJtdLVyoO+CgNgUd\nw+v3Me1Iy8vNt1VKpKqqR6BHysvbBboFdgpsERgnI0Z8RcrLmwXCZg4i06aZ/Z7Ll0cXDr3LWJEY\n+vW4KsFtTL1uUkotB
 o4Clrk22QgMc30emvrOYikqogY6ZeuqauoSG0aYXnz16swN6GEeP8538+fD\nr3/dNxAtKBDwySf9U0s0NemUGenBhEGGZT3uDCaZ1Oe/8kr44Q/NDNUi0Nqq7QCdnR188pM/Z8yY\nas4/fx+OPfYJPve5Txin33766d4qbkEcdxwsWwYnn6wN+N3dZsePlWylC1AD1Lre/y9wSto2pwG/\nR/tuHQ2sMDm2nTlY8k2+bQkLF4pUVnqfr7JSrzchVzOHIHVV0OK+V36zqzCVUUVF72xk61b9etNN\nmalcQOTww/XIfeFCrd/P5LqSye4+9yro94t6r/3uv3PvZs82PU88M4c4hMMItCrpFeAN4IbU9xcB\nF6XeK+CnwFrgNQxUSmKFg6VAZKrmiWo3CDPagl5vol4KE2pBnWGQ0Iui83cvNTXhnaCpyqimJtyw\nbqImqqzs3b6urkeuvPIVqaxsFqXaxEQlBH1Viya/X9D+mbBsmYlNpUiEQy4XKxwsuSSoM49qS4gq\nUKKMyE1nLLnwVorqLeReZs40a7PpTKCurv9sZOZMvX+U0XvvskVKSvaVkSMbpbS03WgfZ+Sf6Ywq\n6szBC0dA+Hs0WeFgsWRM3J5GUUflUUbkfh1KS4tWa0yb1qsucdQvfkItqtBbtMjfaBy2VFebCTVz\ndYkWVib3ve/iPSuoquqUe+/VDXQ/DyaCOtMZVbaqSbNrLiKDtMUykIjLCOxgmkrDnQ301VfNM3Z6\nGYxXroQTT9TF5R0eekgbXJ991t9IHtWA3tAAF15ovr0b0+pkhx6q221iHL71VrjmGv37ZBvk1tpa\nxsaNugtMzxElArff7p9RN5OMq/X12Wfkzfaao2CFg2WvI+68SCYRtOnVzyoqdAdkQrqXlCPc3ILB\noakJTjpJF7CPIy14IqFrJcyfH31f0zQiQam/vXj4YTjxxI945JG/09R0GOGJHvwjjt2/QbrgvPpq\n
 /8SDI0ea1VlwqKzU1d2yzaYdJpRKS6G72zRFYTBWOFj2OuLOi2RS9CZ9puKXdM6L9OJAixcHp71o\na4s38d/++2e2X3m5noWFuW5GcVdta+vhW9/6MZs3XwFMRydfqM2sgegsrcOGwfr1/es4uIVFeu3q\n/faLVvqzo0MXA8qWoGcN4nV5tcLBstcRdwnPsOI4EKwKSCT8O/tksr8qYu3aYOHQ3h5f4r/WVt2B\nZkJHB/ziFzqHU5Q6zz//OTz7rOA94m9m6NBOrr32hxx99CTOPDMZmOwujB074KKLdFv9alJ71bxu\nbjaf+UHf58qvQFTYOjCdZZXEkzMvDsNFrhZrkLbkgiAXyurq3hw3UQgycId5/Eyd6u8S6WXAXLQo\n2IWysrK/ATvT9BxRDK9B7pV+htiWFpFf/7pHrrhiq8yY8Zz88z9/Q4YPP0Rgq89xevocx7nvcaTL\n8Gprpl5JfscMek4yKbCUS4N0QTv/sMUKh8KRba6fYsf5g1VV9f1jVVdnnx8pSrCXE6Dm585ZXd2/\now+LD3C7fLqvNRPPLFNX1ooKkS99yb+Tdntc9fT0yFtvvSXf/vZiqahoEqV2iZOSQqltMmnSNXLl\nlf8ptbWdkkz2hLbZ8dqKS0C42xrVK8lJKOh1r8O82urq/Nf5eZ15Jxe0wsGSI/KZvTNXmAi3LVvM\nyz5mQ1iA2vXXB3c4N9/c/5grVujyll4dW3qZUr9zJxK6Uw26TtPOsa4uOJGeUj1yxhl/lrPPPlsG\nDx4skBCdm8j/3vsJW7/fdsUK3Q4n5qGyUgv/bALVosZ5JJP6nvoNEvyet4oK/1iNoNgI79/HCgdL\nDsjEZ79QBHUSJsItSgbWbPFrU2OjyNixwR3OjBn+158e5+Clggrq3MvKdIflpMhOxySK2RFIwefa\nITBdhgwZItOnT5evf/0Zqa7uinzvw37bdIGSSZoM9/l1CmzzxcmA6/VcRonn8
 BNWZr+PFQ6WHJDP\nDjMb/DqJZcvMhVvUDKzZ4nTmU6eKHHaY7phNInunTs38nKYjX3cNhXTS73UiodNVnHCCvp7m5m75\nv//7P5k79y4pL9/lefzq6jZ5/fW/Sk9PT2i7/O59pgMXp/2mMwj3zMVP1eO0s6am7/N3333+wmvW\nrODzlpVl9r9L/33iStltvZUsfRgI5S+DgthOOcXfVyM9hmHYMP3380JEu6DGyeuvw2WX9fWSMglo\nKi3N/Jxhro8OIjoD6JYt/d1O0wPEDjighxEjXuZPf3qOxYuXcuWVy9m2bRsAQ4Y8w+bNiygpKae9\nvTwVPKZYsqSSww8fadQuP4+xxYvxzX4aFJ8yfrx+rocN67/OjZOx1fEOu//+YNfQG2/UAXxOHMSU\nKfrVL7hy1qzg8/s9t+muzOmk/z6zZ69/L/hMZljhYOlD3G6euSAsiK2jw3tdIYVba6sOTsuklvFp\np2V+3oYG7appQmendwfb2dnJq6++xIYNS3nhhaXMnfs8O3fuBOCggw6ioaGBiRMnMnHiRIYPH77b\nHdMreMzdriD3X6/OcNmyzAcuTz7p3/kmEnD66TB1at+2hgWcVVT0vVf33x/8XG7frmMn/Gphl5Ro\nAeVcT3pUdhDumIzZszdvDd7ajKyFg1JqGPBLYD9AgAUi8qO0bSYBj6ArxgE8LCKN2Z7bEj+Z/Gnz\nzdq1/p1sR4f+03oJiHThtn598HmiBi0F+ajPm6d96qOSTMLZZ0ffz8FRTpjQ2ak72I6ODlatWsXS\npUt57rnn+OMf/0hzqpc89NBDmT59+m5hMGTIkH7HMUnRkR74FtYZtrbqmAk/qquDBy5BHX17O3zu\nc/3bHBQFnUz2P1/YrHvQIB0p7Scc2tp0io077tDPnp9gzRdxzBy6gKtE5CWlVC3wolLqaRH5S9p2\ny0Xk9BjOZ3ERFjQTlaA/7aOP9o0SLdSDG6YeKCvzFg49
 PbqAzP3367aPHOmf08frz+9Ha6vu/G+9\nVX9ub+8bUDV6dO+6KFRV6TxJ2ebiMUWpLh544Ifceuu/0ZrqwQ4//HDOO+88Jk2axIQJE9hvv/12\nb9/aqu9lps9DujokqDN88MHgwD+R4IFLJjPi4cP9o6C9BkojR+q2e3X+iQSMGqWfh0mT/I/b1aUH\nNzfe6H8t+SJr4SAiHwAfpN7vUkq9CewPpAsHS8ykV+iqrIQLLoBvf7s3OZmbMEHiXn/HHfq7detg\n82bd4Z1yCiilH2y/aNJi4Kqr4K67eoWbOwJ5zpzetj/2WG8EczomsyRHKHz3u/3TYTid0IQJ8LWv\nmY/eHZSCa6/NfS4eNyKlwBNceOGFTJw4kQkTJjBo0CDPbb2ihi+5RA8g1q83Fxjpsww/gfO73wW3\n/eijg88zfLj/ffD6rVtb4Ywz/H+3yy6DuXP7tnHKFH8B1tYGp56qZwZXXaWfQy+Kxa4HxOutBBwA\n/A3YJ+37ScBW4FV0RbjDA44xA1gFrBo+fLi/iX4vJyxyM911M5Nc/7W1+jXIFbIQ7q0mni6OS2NQ\n5bD6eu2hk0lMh+NTb+L94p93338JStNtGpzY0qI9ZCoqzArZlJX1yKxZ4b9n2LPneGBFjY8Jekan\nTQtue1Bt5qB4Fj8vrTAXYHfhIKeNQXEM7mDGXHsEAqskjv48joPo9pAEXgQaPNbtAyRT708F3jY5\npnVl9cckOMntkhfkArh1a+YpAqI8zHFFXUf5c5lsG7XGQVwpFUx+Ozem8Rs7d+6UO+/8o1RWNktJ\niVnhe2epqAjv0KNGDZsMIMKe0QULgs/hV041rJiQX8W6qMFv9fV6IGLinht3Kdr0/xWUvCgG/WvY\nEou3klKqHPgtsEhEHvaYnex0vX9CKXW3UmqQiGyO4/x7IybqAse9z3nvt82NN2aeI950GuynhshE\nLRXFaB5mJHzrreg1DuLMqV9ZqVU
 S3d3BRtkg992TTurh3nuf5IUX/oelS5fy4ot/oafnb0B15PZ0\ndOglqK5F1FoGJmnQwzzQysuD7UNnn91fbTplir6OoOypLS3ez6+pC7C7jZs3m9k1ohrjg/D6X8ER\nnzM/gj9xeCsp4OfAmyJyu882nwI+EhFRSh2FTsC+Jdtz55NsMinmApOH1+m4RYI7yNWroxcucTBx\nb427uE6UP1fQfRLReuPTTosmoDIp9OJQUaG9gtztHT1aPz9r1ugOZt994e234bOf1W1cvDg4TfeO\nHU38wz/8htLSHoYOncGRR47mjTf2CTTghhHUoUftOE0GEEH3tKlJe+88+6x2B25r0zaeykrt/vmV\nr+iaE4/rgI9tAAAgAElEQVQ/ru9Xe7sWGD09+nMQfs9v1BoTTU3aG8nUhhXFGO+H//8qm8gYF9lO\nPYDjAEHbE15OLacCFwEXpba5FHgDeAX4E3CMybGLRa0URybFuDFNa7BokVnit0xKHppOg3OlYzVR\nB5ncp6hT+UxLRNbU6Hvt1d4gm09NTXdKNeSnHuqRioqu3Unq4khAFz1lQ/hzmM09PeEEvY2TmsKp\nHZ2eODHO59crMjzoWI2N+e0P/O+ZTZ+RF+LMpBg3YUZRpw1hOs733zcv8u7u6OLI7JmLNBVe9yno\n+qIKqKido/s8fmmrc23DyKStJikbTNJ/mPwXWlvDDfwmKVKiLNXV4c+vewCycKHIPvuEX2dUG1am\n+P+vrHDIC0EjmkQis0yKcdLSoh+SREIvfqMVvxGNkwvGdARWXi5ywQV6BHzTTeZF6gudryko6Vkm\nAio9p35lpb7/s2f7X2ttrfe9uuuuLZJIdBRcIETt0J1cUUEj6ro681GzaZK76urMZ7ruY2RStyOo\njfnOPZbrmYNNnxFCkC40SKfb1JQff+WqKpg9O7jeLXjrOL1ywQSRSMAVV8CPftSbpsLEsBykv+3p\n0f7fuSaoiH
 0maUGc+/ngg9q3f+NGXU7zo4/039OLzk544AE4/vj3WLp06e5l7drpwHciX5Pf9USl\nokIvmaRsOP98OPxwrfvu6Ohr/C0vj94Wpfzvn0NQipR0qlM2+ZKS/tdXXx+9fUFtTLet5NoWGdUu\nEpk4JEyuloE8cwA9yihmourOs4l3yEVxnShs3Rq9dkOY6+2KFVFHsD0C7QLHCCAf+9jH5KyzzpJz\nz/2db/pqv2XqVD17M1HrhC3f/nb2apCgWIK6Oj3DCHNhjqvqXPpv69gp4lDzmM6C82V78DoPjOmS\nGPrfrA+Qy6UYhEOYvt5EB1kspHd2QcVZnD+gY+Csrg7uiPz8xd3kq7hOOs4fKP3cVVX9/7DOPXIM\nnkF1A0yD4LyExL33viXd3d0ikpkNw+lso/jiey1VVfGoQsI6dkf15KjfGhv7/96m96GmxsxGVlUV\nf2dsEqOQ75oo6TaOuOIcsj5ALpdiEA4i4fWB/R7OYqp/sGyZ/kM5I65kMtjbI5HQ2zo55v1yzbsX\nt97ea9RdCNtD0B81Xe/s/M41Nf7X6Py5Fy3KbtReVdV3NJ0eqR02Mj7hBD1zCGqryRJXZ5WJoPIa\nSZv+BsuXh3sPeVXQi4OwWUGhbWzEFCFtbQ4GBPkkP/mkuQ6yUCxfDhMn9m2jo6tWynufdHtKWNBX\nRUWv3t4JzGlr00sioXWjX/lKPLUiouhygxK2lZTAE09oX34vn3EvurqEO+9cz/PPv097uxOy44Vz\ns71vcGsrXHxxr78+6HxYI0Zon/4PPtBZSP3u17PPwooV/gFeYbr79NoF2RI19gH0vU6Pc3H/15Yt\ng1/9ytteMH48/Oxn+h56/b7JJBxySPbX5UVYjMJAqIliRBwSJldLscwcgsj1KCHblBMtLcFT8Kqq\nvuqTmprM/OSrq3un1F61jZ3ZSLb3Kooud8WK4NGl20vJXN/dJXCDwHSBVt/tysszU/k43j1
 RVE1R\nKpI1NubGxTIb996g3z3ILTTuNBQZ4fEH3VNmDlkfIJfLQBAOQQ9opu5yDnEYtRYtCu7slep1SXX0\n7FETxbmTly1cGLxtNjaHKLpck9iB9FrBJp15aWm7jBu3TubO3RRoc6iryzxAy7kW5/c36WC9guvc\nyQdnzdI2plz63ac/ryZqt2zjXAoVhBp08tblK/MvtFxCahC8IzH0v7F15LlYBoJwEMmNJ05cRq0w\n3/GKit7kc6Yjv9LSvoZqd1bLqVOD9z3hhMz/zFET7oV1zvX1Ijt3dsgLL7wgZ5/9iJSWNht34E62\nWi9hV1urr2f5crNjBV3LwoXhnWxQB5vvzjM9aCzsmUok/JPmZXLOXAq/ficN+IOuWN6Wv/ue9iMf\nCbaGdLHgV6O2pUUvmeQPCktE5uS9CdO/O7rgsFz2Dz9snkzuggv0tabrWleu1Pltgvj4x8Nzyvhd\nUxRd7urV/hW3QCgt7WLUqCsZPHhhqspZJSUlH5ndAHp163V1MH8+PP20/nzaaToJXCKh70cmsQju\na1m/Ptyn3y9OwzinVYwO+elJDA8/XOdD8quC19YGl1+ut8u0dkXUxImxEPIHHf+33/L+++dklTvJ\nCI8fucTfEBYJKxxiIqhGrUlWynRMOkK/TKdXXqm3GzZMB175FUlXCp56qrfjNenEKip0EJxXIaHJ\nk/0LwDucdlrwnzkoe+uwYfr86YV1oH8HuSUkrWN39z00Nz/H+eefv7uwzVtv1fUz3IfR3a0FwH/9\nV9/vnfuRSZCa+1pMDL1+hYmMBhgHx5gu14Px47UQcirleRmPd+zIbABVUAz+oHkRWnGmCE4jrpTd\npwA/AkqBe0Tk+2nrVWr9qUALcL6IvBTlHIXIfBqFqB4KpiN+v4jeoUP9R4U33RTc1tJSvTzxBBx3\nXPi1ubnxRt153ndfb3Wu007Tr2HPaFg95KCR7gkn6DZ7CQaHhgZoaW
 nhT3/6Ey+8sA8wFj9voauv\n/hpz517c57s//MG/ZrAfft4n2fxn3Z19WBRsfb2/x1HwMym880YbXBJjulwfnCj+YcPgoou8f8NM\nBlAFJZO6o7kgmxTBIcSRsrsU+ClwErABWKmUelT61pCeAhycWv4f8LPUqxFx1gLIFSaduVP+EOD2\n24OvJ6xmAWTe+XR36//8tGm9KaNv90y23p9PfQr22w927er97qGH9Ig+SP1RWRleDzmoQw0bgXd0\ntHHyxJP59It/ZEh3Oa/yd/wEQ1UVHHlkTb/v164Nzv3vRU0NjBjaAfc/1EfSr12byOA/K1SXd7Lk\nymdJMAlI9EtP7pSDVcq/HKxD4DMpTYyY900o9ZG2cfTWaSOg9ev+kY4O75waGbt4FmrUGKWoSC4Z\nOTL6iMaUbI0WwBeAp1yfrweuT9tmPjDd9XkNMDjs2GPHjs17tKEfYS6lQV5LtbXae8W0cptDWPBd\nttGxzjkXLjRPW5DJOSsrzYyO2VxTCTvkHnWutJaXy6+ZLjXs9N22miZpXb6y3/kzScVdX9sprXX7\n9fuRFjX+NfKxFN1yMzd7Wi8zMboGunqyRVoJsHTnwI1oUfU3JOmTJiQjF8+CuioVwflFtNdD2p9m\nLIiE9K0mS/YHgGloVZLz+avAT9K2eRw4zvX5D8C4sGOPHTs2ss9wXKUo3Zg+A37bmXYSQdeT3ilk\nWlPA65zTpsUjaPyWujqz3yH4moJLXSq6ZA43iIA0cqMoun2PM5O7PUcW5r76PVJR1iX1dd2yInm8\n50atVR+T+kRLtN+CHbKI6b1fxDD6WbFCpL66XZLsFEWXJNkh9WyRFYyL/jCa4jOia6VS6tU2z9NF\nvtRiGzXm1VXKdW6PexCXcCg6g7RSagYwA2D48OGRdPm5UD+ZeHyI9M5s77hDr9uwQasdOzrgssvM\nztXcDO+s6YT7/2v3NLmqoYFzzuk/TY4rI6Nzb
 6NGt0bhqqvMZvoNDTBrVg/ezhaCn5oIoIYWRqAf\nhpGspYZmmqj12G4XE1iuf9C5c7UyPEUiAUsebWPyxDbapJI2Ep7nrKCDb3Aft3VcT0J5q2USrdtY\nwgQms4QuymhWSWoquyiVLnpUGbva+qtXyuiiAVeV3RhUO+PHw/tX3cbiOa/zDgcygndo4GESBBhv\nIDvViI9+MEE7SxJnMVk9TVdJRVblMY3d+XJNQVylUuTQGA3xGKQ3Am4nzqGp76JuA4CILAAWAIwb\nN05M7T5xl6J0WLwY2tu9O6b2dt2/pNsP3CH+c+aYqwNrqroZMW8WlDwQKt366qKF5mYtpII6UM9z\n1miD8jPPmO4R3EmnoxSorr4Cz60X3rRpE8uWLdudvnrHjkrgKaAcqKGiopPy8hKUKg322KFzd8fa\nwMNcwk88tyt3d8CNjdpK6vieAuPXP8z71d/iweZTuZif0eZRh7maZm7r+haJruAOdjyreJ8hLGYq\n78hIRsgGGtof4LWqo5isHqGrqpbmFkUNTZTRxRJO7ttpR1XE++jfqw79NOckb/X+EwXltM5Udx8w\nohvftpz3Z9/O4lHXZefiucfkqMiCHBqjgVjUSmXAO8CBQAW6FOjhaducBvwe3ascDawwOfbYsWON\nQ+RzFbI++4L1gSoNvwAld4I2U/VPvdrmrQcOmCa3LFspi6q/IXMqviON3Ch1bNUqBJXeZu9rSI/G\n1W31L0npr67xuffVXbKo+hu7dW3dNTXSXlMj32tokM985jOCljZSXV0tJ510kvzbv/2bPPPMH+W+\n+zp6Z+rLV8qK5PFSz1apYperfT1STZOnmmQF46SeLZJkR7A6JZHoqyN0GT6Mj5HB0kJCFpWfJ3PG\n/bcsqvwX7989kdA6PxN1RZDuM+xPFGdOa5H8ZJ4rdI6KYsDnHhSNzUFEQLuovgWsBW5IfeeuIa3Q\nHk1rgdcwsDeI9EZIm+j8
 c1KKsqVFZlUsCBAOPb7ZSp3nM0yPvft6qttlRdWEaA+7Rw7sFhKyiOky\nJzFHFi5ol4ULRebMXC+NlXNSgsPp6HZKfW2nZ7rqOdNelsby70h9n+11x3gfX5NadgiE1TVO9T14\nC7ytIGecdJLMbWyUt265Rbpuvtm7Y3LpVZ1ru4mbZRZ3yc3cLIuY7mtY3X0vuCFwu92dpIc0j3SM\nTBYnL3rQNkF5rtPuke915dN4mo+kR0WRWKnA+NyDohIOuVrc6TPC7D4ZDySCLNiLFslN5bcGCoeg\nTt8RSF7/y7q6tCRos78bTbqZFkb26Fx3d3R1+/WOGt3Xn5K0fh1jCwlZyHkyjQdlWvnDsnBBuyxf\n8IbUs62f4XOpzyi7J5nU5wnrsLK1vI8zHOWbSvNcLc71hwkKrw7d9OHPp/E0H8KoGLyFCo3HPRgD\nttiPm4wGEmEPV2OjLOIcqabJ87gVpZ3GNaRD/5dRpJtpIqRp04L9VKurvSvaNDYad8jd1dWy9F/+\nRVrKyjyFSU/Q/n4pU90/WDb+rTU1+vpNqvKkS3OTajJxLjU1OjvetGnhyZTSH+icTJtjIB/CqJDe\nQsVC2j0oAVvsJ51IAwmTqfiiRdJas6/Us8V7s+p2335n9//X1Lc2inQzHU0nEnqJ2rnW1RmPnntA\n/pB6jXSOigqd19prnVsYmpQY87s+t0qlri64YlF6MMbWrf7tc19DnEJkzhwzYeiVZXBv179bdkNM\nKbtjSdBULDhFOObP144o8+drLyVPN1YTV7iGBhLl3SzhZOrZSpKdKLpJspN6tZ0lTwlPP9ZGfXUH\nyYp2lBKSSelNafDaShgyBGbOhJtv1q+DB2uf23Qc96P6ep1nQin96pUfwdRLwam2I2J0/3bT3Q1X\nXonU19NdXa0txj6bKmCSX1KpIDo6/BMxub1NGhp6Q8LTSSR0xZdly8Lvm1I6/4Yf7e1wxRW9v00i\nocO
 +/aiuhvfeC94mkdAP4vLluj1OVR8/hg7tDWsOIt0bJ+ge5TNa17JHUXRxDtli7HZs4gqX6rDH\nT57M+52jWNw8mXcqRjGibD0NT80kUSkweTLvqzIWd6TW9ayn4bGZJEYfDkN8fGsnTYKrr4ZRo/r6\n8YWVmALtrvjhh1BeHp6uM0N6mpp48IEH+NeyMo7bvp1DgOsAP2/DEr9ycg7l5bpjbG7WnWpLS7DA\ncvsop+eP8PIXBv/7ZlriDfqWJlu82L9MHsB11+lcIqa5Ld5/X6cfXbAguA0mASzpuXvC7lExJSGz\nDBj2OOFgTFAARXm57iDa2nZ32FWLF3PO7o7nWt25DRkC27dTBZzD/dCBXs54SEfD+c1MWlr0iDKZ\n7B/HYJKytLMzZ4IBoAno+NvfuOOgg9h36lSGX345lT/6kX/H5pf21WHKFD0qHjQINm+GX/4yWppR\nE6Hpd9+iBgo5s8aw2ZkjOEza5rRv6FD/+p1K6chJp6MPynPtNRsIakexZ620FCdx6KZyteSk2I9j\nA5g9O1hfXFMT7PkQpueNkpMi2zJoYUsiEan2Z49zDelG6myq2TvHmTkz+L4kEvF6m0Q1aDsG3Fzo\n8YOOWVnZN6ahpUW33W03ysQbx3r07HVgy4RmQPofpaqq99Wvs6iu7ltf0REuJ5wQ3MFMmxY9qVKI\nW22mLp2dJSXSHSYMHIEYZNwNuk9OMeqgos3O/fS7jvJykS9/OV6vk6j3zcSl1R04FiWJl3HQi6vz\nzsYbp1jyD1nyihUOUQn6o1RUhI+snbqQtbXhnU0yaVYj0d0pzJwZ6lYbZQTc41raMPAmOvFE7UoZ\nNFoOE4hOMeogd8yamnAPnzhHt1HjFtydpt+o+777Mh+N9w1FN2tHplgvpr2SuITDHuWtFEiY7jlM\nh9/UpJddu8Iz1JWV6Xw9S5ZAbf/kb/2oqYFf/UobRJua9N+3qanXQNrWZubF4kK5
 lkpCsiElk/D1\nr2sDa5CR/uMf19v6XcOoUVrvf8QR/vezpQW++tW+3kXppF97Nvh5gSWT+rcJ8nByu7/Nng1f+xpc\nfDHMmhX8WwXhPua0af66f8f2kQ02/5AlC/Ye4RD0R+noCHZJjEJtbW8HM3q0f+1QNz09/p4xLrda\n8XNXTEMiNBfoNXAGCSAnQ5+Jy2TYcSZM6O0g/+Ef/F084+ggwdvH+e9/h48+Cvd7rqqCgw+GH/9Y\nG9K/9z3/ikCm7XWM50cc4V/aLo7OO+x3yFe1MsvAJI7pR66WWNVKQVNsE1WH6eIuXmASwBVipO1R\nSpZMmCDHHHOMHF1aKltAdoB0m6iKvFQ/5eW9+XzS1SFbt/rfhyg5eqIE9MUZ3ZuLYh5RHAGitjfX\nah+bf2ivhL1GrdTaqutrzpmjXzNVMwQFCpWXw1NPBas6TOnu7h09hrlDdnXBY4/pkbTPCG+XCL9Y\nvpzu7m4mXHUVKxcvpuyeeyi56SZUdf900oHU1Gh31IUL+4+Wly/Xrpbp6qDq6r7qFmcUftddetR/\nyinabfezn+3dx1HleKnUurrgtdd6P8c1ul0ZIeAwClFcYaOOxnMdvBYlsNJiSScbyQLMBVYDrwKL\ngXqf7d5FZ2N9mQhSbeyhh8brhhc26t2yRRtlv/hFkdLSzGYO7tGjgadMRyIh3541S3b4nK8jmZRd\nf/97/2vxc3Wsq9NGc7/R4sKF/UfWTz/t38bqapFt26LdR6d9oblFJPvRbUuLviaTPE3p+5nMMqI4\nAmQyGs+Hq6nNP7RXEaWPDVqyFQ6TgbLU+x8AP/DZ7l1gUNTjj/XroL3+hKZ/dr8/ivMnDXLXNFnc\n6oDWVv+OOrV0g1xQWiozjjxSWhIJ6ayqkp6wTiLd4yU9pbNXh+N4WaV3QvPnm1+Pc//iLrCRaQfp\n7BeUqM5LPRPlfCausNl26LbztsRIUQiHPgeCqcAin3WZCQe
 /P2N6krRsR1/ZBJgFdJAfrlsnHSF+\n/z0gnQ0Nve0I6yRMO2f3sUwzk3ot6Xp0004/qi0hagdp+pu5z5XJLCNoZlNd3eu+m0ncg8WSA+IS\nDnGmz/g68KCf9gp4RinVDcwXXQrUE3cN6bF+G7W3w4UXwrp1+m962219PUii1geNoxZrRQU9VVU8\nfdVVLL78cpYuXcqRq1czH13w0g8FlDkeTSaJoUxr57qPdf/94Sku/Cgv76tHN3WPNK3v6hC1Fq/p\nb+acy0k90trq7yHkVXvYJLfTypX6HHEWL7dYCkyocFBKPQN8ymPVDSLySGqbG4AuYJHPYY4TkY1K\nqU8CTyulVovIMq8NxV1DWinxbVhXlzaqBmFaaDzLWqydJSU8mEjwjR07aJ89m9raWo477jguHjaM\n5DPPaAEWxPHHm58sE9/1bK4v3TBq2ukHJZCLw9hqek1lZTq304gR4cn3/O5fWN6iXBQvt1gKTKhw\nEJEvBa1XSp0PnA6cmJrSeB1jY+p1k1JqMXAU4CkcYsXUVzyowzM5TU8Pv/vCF/jtvvsypraWTx17\nLKX/+I9aMD3/vO5AgrjkEn3+887zXu9OnPbhh9FG5JDd9T31VN/OzbTTjyNTaFDCuLBrSiR62/D7\n30ebZXiRSWI/08GJxVKMZKOTAk4B/gJ8ImCbGqDW9f5/gVNMju9rc4iyuG0TfhikWPCLKegB6b7w\nQq3TdwyjlZX68zPPmHu6KNXfK0ikvz0lLP+Rl6476PqC2ve733nr0aPYeDI1toadI+iaEgn9u0et\nJpeJt1GxVmGz7LVQDAZp4K/AerSL6svAv6e+HwI8kXo/AngltbyBVkcZHT9vwkFEev78Z+naZx/p\nKC/vk5eoCaQVAhPX+eZlqqyM5v00a1Zfr6ug/EzumsMmBnjTPEFOdbMFC4I751x62Jga3U2FlGkw\nYibeRjZ/kaXIiEs4KH2s4mRcWZmsqq
 rKWN0D6OC5G2/s97WI8Je//IWlS5fuXnZ89BFTgbE1NYwe\nPJiPH3IIgydOZP9PfAL1zW96t6Oy0t/AGZXx4+Htt3vVMBUV/sd21FCDB/vXEEjHUdP45ft3vg/S\n0dfX516Pfv/9OojN73dvbNS5joKuyU1bm75PXtfjVJM7++zMrino2Pm4VxZLGkqpF0VkXNYHikPC\n5GoZe+SReuT1jW9kNmtwjdy6u7vl5Zdflh/96EfS0NAggwYNEtAVMIcOHSrnnnuuLFiwQNasWSM9\nPT19RXGQCiOsznBQ3WLTGUi+VRaFHg2HqYESieIKNrM1EyxFBEXoyho/JSXamHfOOToj5imn6FG1\nO8WDX2UtoEspfrp+Pc+edRbLly9n27ZtAHz605/m1FNPZeLEiUyaNIkDDzwQFZQyI8i4+vnPw7PP\n+u8bJRVHlFrMuUyclu9snumG52HD9IzML1WKSHRDr2nFtkzI9Ni2QpuliClu4eDmi1+E9eu1OmH1\najjoIBg3TmfW7OhA5s1Durqgs5O2khI6eno4adcuVl13HSNHjmTq1KlMnDiRiRMn8ulPfzr6+f06\ngAceCBYO112n8xCZqIqi5I3KZeH4qDEK2eDEH7iFbmmpzlTrR3t7ZgIqaixFLo/tdd02NsJSRBS3\nzWHcOFm1apX+kPZnkpoaupXi95MnM+mRR6CrixqgE+hWirtOO41h06czYcIEhg4dmrtGbtumE755\ndey1tbBpkx7pOkLlgw/gF7+IHneQSOhOMT0AKxfkS4/e2rq7Dnc/gmw5yaROGjhQXUSDrtvaKSxZ\nEpfNofizsgK0tiJOoFGqwIpqaqJs1y5O++1vqe3qohZ9MZVAtQj/+vzznNPRwdCFC7PL5hqEExmb\nrjoqL9fZTM85R6s/lNLvb7xRF9TxqwfgR12dVqsdf7x+Xbcut6PLfGXzDIoRKCvTo3G/dbmaNeUD\nk9gIi6XAFLVaa
 deuXdxyyy2U/eY3fGv7drxqqvlq9Ldv1x4vTiGfCy+ERx7RI3kvHW9U/a9XZKxD\nZ6c+54IFsGhRX3VBlIA0p2Pu7tYCrrkZVqzQ74NmDnHosnOpo3cIsm20tMCMGfDgg5kH0RUrtkKb\nZSAQh1U7VwsgSin56eDBwXEGUZaqqv4eJZl4m0QtXF9dLTJ7tnlt6URCxxqYpL12M5A8Z0y8ovbE\njKWF9gaz7NGwN8Q5HHzwwbJy5Urqn3gi2O89G+rr9d9yxw7vdX763zlzdFGZqPfPqcGslJ5h+Km7\nkkmtQvrlL72v20vvPtB02UG2jbo6uPNO7YSwp3ny2NgISw7ZK2wOdbW1WjCsXu1fsD5b2tr8O+gg\n/W9QBbMgmpr0UlKiXXP9aG7W1x1F/TDQdNl+to1kUnsrXXZZvFXd0omrymBUbIU2ywCgqG0OvPqq\n7hiam7V7Yy4I6hCC9L9BCehM6O7Wo/xk0t9l9NBDtY3B1KV0IOqy020bQ4fCFVfkPstpoV1J82HT\nsViyoLiFQ3d3b8eQbb0FPxIJrRrycpsM8un3CoyrrtaGVBNVU3MzfOITwTWEv/tdPaL1W5/usZPP\n+IQ4Sa89kessp8WSZjuXcRcWS5ZkpVZSSt2ilNqolHo5tZzqs90pSqk1Sqm/KqWuy+acseOkdvbC\nz2XSUUc8+STccYcOcmts1N5Jy5b1VRf4UVMDhxwSrF6orIQrr9Ttq6zU+wWpH3JdsD4f5GP2M9DU\nbxZLAYhj5nCHiMzzW6mUKgV+CpwEbABWKqUeFZG/ZHzG0tK+lc0qK7VNIijlQlWVXpdI6FfHLfLO\nO+HSS/tvX1vr3QF7qSPSg9IcdcFbb8Hcud5xDU5nnUh4qxdee02rnbq69KymslJve+21cM013gIt\njhoKhSYfs5+BqH6zWPJMVt5KSqlbgKYQ4fAF4BYROTn1+XoAEfle2PHHKSWrvFaUl2sBcdppcP
 jh\nMGoUTJoEBx/s3RE7mTfPOksXfnE64aB96up0YR13h5qJN5CJMEknW68jk0yluSbTWIt8ePIEZX0d\n6NHXlr2eosjKCtwCvAe8CtwLfMxjm2nAPa7PXwV+YnL80HoO9fW9hd2nTesttmPiO75ihY49MMjo\nuptM/dOj+uoPdD/4bGMtch2rEZRlN5OCPxZLEUG+srIG1ZAGfgbMAST1ehvw9WyElVJqBjADYGzY\nxh0d2rulpCQ4BqKpCdas6f3sGCSD0lh4qRcyVUdENTwOZLVHHMbeXHvy7AnqN4slx2RdQ9pBKfUf\nwOMeqzYCw1yfh6a+8zvfAmABaLVS4Emj5CiaNw9OP113PEEGSQcv/Xa+vIGyOU+YOifXaaLjqqmc\na08e60pqsQSTzbQDGOx6fwXwgMc2ZcA7wIFABbpc6OEmx4+lTKiXysCkprCXeiFf6ohMzxOmjslH\nag1bU9liKSjEpFbKNkL6h0qp15RSrwLHpwQESqkhSqknUsKnC7gUeAp4E/iNiLyR5Xkzwxm5hkU3\nV1d7qxeyjWw1jcjN5DxudU4qcy1NTfrz5Mk6tXjQ+riig4PubTHHWlgslj4UdW4lX28lh7KyaMFx\nSt2VA7YAAAkWSURBVOl4hKuv9veIqa6GjRt1R+xHJt5AfkVtrrpKrw9SAZmcJ8wDJ2qepkyxeYMs\nloISl7dScUdIB+Hk34kiHGpqdOc0d64OLrv9dm+DZJBggOj68CAj7U03aaHllb4hynnCjNhR8zRl\nijX2Wix7BANXOJSVwWOPwRln9HZCiYTuiP1obtZV2Fpaekfu116rO+dcGiTDDOCOigcyT98QZsSO\nmqcpG6yx12IZ8BS3WqmsTFZVVPTt8KurdSEdZ4TtqF7WrNEeSVGrrMVd9tLLEyhKeu9MVTxh6px1\n6+DAA626x2LZw9k71EpHHKHtA2vWwObNOlHdIYf0HYU6qpf779fxDl6Ul
 +t1Xsn14krmFpTlM0r1\nt0xVPCJaVXbrrfpzer1px5ht1T0Wi8WA4hYOJSXx6Nw7O/33i0PfHhb4tW6df0K8dDJR8bgFU1ub\nzsNUWdk/D5NV91gsFkOKWzhEIWh0nmlablPCAr+eeKLvqD1oBhE1e6qXYHKu8/bbtXBwY9NEWywW\nA4q6ElwkgtJVZ5KWOwom6S6cUfv8+doG0dgYTyUwm37aYrHkgD1n5hDmQgm507ebprtIH7VffXX2\nKp6BnIfJYrEULXuGcHB7Cd1xh/5uw4b+HW6u9O1BJUODZiZxqHgGavU3i8VS1BS3K+u4cbJqVWCM\ndGb1EnJBodphI5ItFouLvcOVNYxiqQUMhfMEshHJFoslBwxs4RBXeui4KJQnkHVRtVgsMZOVcFBK\nPQiMSn2sB7aLyBiP7d4FdgHdQFccUx7AGmPdWBdVi8USI1kJBxH5ivNeKXUbsCNg8+NFZHM25+uH\nNcZaLBZLToglzkEppYB/Av4zjuMZExTbEEf8ghvTWgwWi8WyBxCXzeGLwEci8rbPegGeUUp1A/NF\nlwLNnnwZY4PyJuXTI8pisVjyRKhwUEo9A3zKY9UNIvJI6v10gmcNx4nIRqXUJ4GnlVKrRWSZz/lm\nADMAhg8fHta83Btji8kjymKxWPJEqHAQkS8FrVdKlQENwNiAY2xMvW5SSi0GjgI8hUNqVrEAdJxD\nWPuA3Bpji80jymKxWPJAHDaHLwGrRWSD10qlVI1SqtZ5D0wGXo/hvPnBekRZLJa9kDiEw9mkqZSU\nUkOUUk+kPu4HPK+UegVYAfxORJ6M4bz5wfGI8sJ6RFkslj2UgZ8+I9fY9BQWi2UAEVf6jD0nZXeu\ncDyi4kivbbFYLAOEgZ0+I1/Y9BQWi2UvwwoHU2x6CovFshdh1UoWi8Vi6YcVDhaLxWLpR1F7Kyml\ndgFrCt2OEAYB8SYUzA22nfFi2xkvtp3xMUpEarM9
 SLHbHNbElt47RyilVhV7G8G2M25sO+PFtjM+\nlFKx+P9btZLFYrFY+mGFg8VisVj6UezCIZ7U3rllILQRbDvjxrYzXmw74yOWNha1QdpisVgshaHY\nZw4Wi8ViKQAFFQ5KqX9USr2hlOpRSvl6ACilTlFKrVFK/VUpdZ3r+48rpZ5WSr2dev1YjtoZeh6l\n1Cil1MuuZadS6vLUuluUUhtd604tVDtT272rlHot1ZZVUffPRzuVUsOUUv+jlPpL6hn5lmtdzu6n\n37PmWq+UUj9OrX9VKfV5033jxKCd56ba95pS6n+VUp9zrfP8/QvUzklKqR2u3/Im033z3M5rXG18\nXSnVrZT6eGpdXu6nUupepdQmpZRnyYPYn00RKdgCfAYYBTwHjPPZphRYC4wAKoBXgMNS634IXJd6\nfx3wgxy1M9J5Um3+EPh06vMtwNV5uJ9G7QTeBQZle525bCcwGPh86n0t8Jbrd8/J/Qx61lzbnAr8\nHlDA0cCfTffNczuPAT6Wej/FaWfQ71+gdk4CHs9k33y2M237M4BnC3A/JwCfB173WR/rs1nQmYOI\nvCkiYUFuRwF/FZF3RKQDeAA4K7XuLOAXqfe/AL6cm5ZGPs+JwFoReS9H7fEj2/tRNPdTRD4QkZdS\n73cBbwL756g9DkHPmsNZwC9F8yegXik12HDfvLVTRP5XRLalPv4JGJqjtgSRzT0pqvuZRlhZ5Jwg\nurTy1oBNYn02B4LNYX9gvevzBno7if1E5IPU+w/RhYVyQdTz9CuABFyWmurdmyt1DebtFOAZpdSL\nStfsjrp/vtoJgFLqAOBI4M+ur3NxP4OetbBtTPaNi6jnugA9onTw+/3jxrSdx6R+y98rpQ6PuG8c\nGJ9LKVUNnAL81vV1vu5nGLE+mzmPkFZKPQN8ymPVDSLySFznERFRSmXsehXUzijnUUpVAGcC17u+\n/hkwB/0QzQFuA75ewHYeJyI
 blVKfBJ5WSq1OjUpM989XO1FKJdF/xMtFZGfq69ju556OUup4tHA4\nzvV16O+fR14ChotIU8p29N/AwQVqiwlnAH8UEfcIvpjuZ2zkXDiIyJeyPMRGYJjr89DUdwAfKaUG\ni8gHqenTpkxPEtROpVSU80wBXhKRj1zH3v1eKfUfwOOFbKeIbEy9blJKLUZPO5dRZPdTKVWOFgyL\nRORh17Fju59pBD1rYduUG+wbFybtRCl1BHAPMEVEtjjfB/z+eW+nS+AjIk8ope5WSg0y2Tef7XTR\nTyuQx/sZRqzP5kBQK60EDlZKHZgalZ8NPJpa9yhwXur9eUBsM5E0opynnz4y1QE6TAU8vQ1iILSd\nSqkapVSt8x6Y7GpP0dxPpZQCfg68KSK3p63L1f0Metbcbf9ayjPkaGBHSkVmsm9chJ5LKTUceBj4\nqoi85fo+6PcvRDs/lfqtUUodhe6Ttpjsm892ptpXB0zE9bzm+X6GEe+zmWsLe9CC/mNvANqBj4Cn\nUt8PAZ5wbXcq2ltlLVod5Xy/L/AH4G3gGeDjOWqn53k82lmDfrDr0vb/FfAa8GrqRxlcqHaiPRZe\nSS1vFOv9RKtBJHXPXk4tp+b6fno9a8BFwEWp9wr4aWr9a7i87Pye0xzdw7B23gNsc927VWG/f4Ha\neWmqHa+gDefHFOP9TH0+H3ggbb+83U/0oPMDoBPdb16Qy2fTRkhbLBaLpR8DQa1ksVgsljxjhYPF\nYrFY+mGFg8VisVj6YYWDxWKxWPphhYPFYrFY+mGFg8VisVj6YYWDxWKxWPphhYPFYrFY+vH/AZ8m\nCS/bM+YRAAAAAElFTkSuQmCC\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYcAAADSCAYAAAChKgyOAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnXucFMW593/PXmZmdwd3FRRBIFyioEcT1MV4CyAq8QqK\ne4zi/QaKRo1XFEHPEhONl/BGo2KMi8cs0QQloh4VjBAw70lg9Q2gBkSURBBvu0LY3dnrPO8f1c32\n9nRVV8/07M6y9f18+jOX7qmurumup+q5FTEzDAaDwWBwktfdFTAYDAZD7mGEg8FgMBhSMMLBYDAY\nDCkY4WAwGAyGFIxwMBgMBkMKRjgYDAaDIQUjHAyGkCCioUTERFTQ3XUxGDLFCAeDoZsgwf1EVGtt\n9xMRdXe9DAYAMCMcg6H7mAbgLADfBcAAlgH4BMAT3VkpgwEwMwfDHgwRDSSiF4joKyL6hIiud+y7\nh4gWEdHzRLSLiN4lou869h9MRCuIaAcRvU9Ekxz7iojoISL6JxHtJKK3iajIceoLiOhfRPQ1Ec1S\nVPESAA8x81Zm3gbgIQCXhtcCBkP6GOFg2CMhojwALwNYC+AAACcCuJGIfuA4bDKAPwDYB8BCAH8k\nokIiKrR+uxTAfgB+BKCaiEZav3sQwJEAjrV+exuApKPc4wGMtM45h4gOllTzP6z62ay1vjMYuh0j\nHAx7KmMA7MvMlczcwswfA/g1gPMcx7zDzIuYuRXAwwBiAI62tjiA+6zfvgXgFQDnW0LncgA3MPM2\nZm5n5v/LzM2Ocv+LmRPMvBaiw/8uvIkD2On4vBNA3NgdDLmAsTkY9lS+BWAgEe1wfJcPYJXj86f2\nG2ZOEtFWAAPtfczsnA38E2IG0g9CiGxWnPtzx/tGCCHgRT2AvRyf9wJQzyYbpiEHMMLBsKfyKYBP\nmPlAxTGD7TfWjGAQgM/sfUSU5xAQQwB8COBrAE0AR
 qCzSigd3oeYVay2Pn/X+s5g6HaMWsmwp7Ia\nwC4iut0yIOcT0aFENMZxzJFENMWKS7gRQDOAvwL4G8SI/zbLBjEewJkAnrOExdMAHrYM3vlEdAwR\nRdOo438DuImIDiCigQBuBrAg3Qs2GMLECAfDHgkztwM4A8BoCPfQrwE8BaDUcdhLAH4I4BsAFwGY\nwsytzNwCIQxOtX73GICLmXmD9btbAKwHsAZAHYD7kd6zNB/C8L0ewHsAXrW+Mxi6HTLqTUNvhIju\nAfBtZr6wu+tiMOQiZuZgMBgMhhSMcDAYDAZDCkatZDAYDIYUzMzBYDAYDCkY4WAwGAyGFAIFwRHR\n0xDugV8y86HWd/sAeB7AUABbAJzLzN94/PYSAHdZH3/CzM/4na9fv348dOjQIFU0GAyGXs0777zz\nNTPvm2k5gWwORDQWIuT/vx3C4ecA6pj5PiKaCWBvZr7d9bt9ANQAKIdITfwOgCO9hIiT8vJyrqmp\nCXI9BoPB0KshoneYuTzTcgKplZh5JUTQj5PJAOxZwDMQ+end/ADAMmauswTCMgCnBKyrwWAwGLqI\nMGwO/Zl5u/X+cwD9PY45AI4kZwC2Wt+lQETTiKiGiGq++uqrEKpnMBgMhqCEmniPmZmIMvKNZeYn\nATwJCLVSKBUzGAyGLiSRABYvBjZvBkaMAKZMAWKx7q5VMMIQDl8Q0QBm3k5EAwB86XHMNgDjHZ8H\nAViRzslaW1uxdetWNDU1pfNzA4BYLIZBgwahsLCwu6tiMPR43IJgyBDgzDOBtjagoQEoKQGuvRZY\nuhQYM8a/vFwhDOGwBGK5w/us15c8jnkDwE+JaG/r80QAd6Rzsq1bt6JPnz4YOnQozJoowWFm1NbW\nYuvWrRg2bFh3V8dg6NGsWQNMnNhZEDQ0AE4/n/p68TpxIrB9e8+ZQQSyORDR7wD8L4CRRLSViK6A\nEAonE9EmACdZn0FE5UT0FAAw
 cx2AuRBZLNcAqLS+C0xTUxP69u1rBEOaEBH69u1rZl4GQ4YkEqLD\n37FDCADmjlcv2tqAF1/s2jpmQqCZAzOfL9l1osexNQCudHx+GiIPfsYYwZAZpv0MhsxZvFh0+Lo0\nNAAff5y9+oSNiZAOyI4dO/DYY4+l9dsFCxbgs88+2/156NCh+Prrr5W/WbFiBc444wwAwJIlS3Df\nffeldW6DwaAmkQAWLgTmzhWvfpPrzZtFh69LSQkwfHhmdexKjHAIiEo4tPkMI9zCISiTJk3CzJkz\n0/69wWDwZs0aYOBAYPp04O67xeuAAeJ7GSNGiA5fl4IC4bWkoq5OGK9PPFG87tihPj6bGOEQkJkz\nZ2Lz5s0YPXo0br31VqxYsQLf//73MWnSJBxyyCHYsmULDj300N3HP/jgg7jnnnuwaNEi1NTU4IIL\nLsDo0aORSCQAAI888giOOOIIHHbYYdiwYYPstACEcLnuuusAAJdeeimuv/56HHvssRg+fDgWLVq0\n+7gHHngAY8aMwXe+8x3cfffdWWgFg2HPQWY72LFDfC+bQUyZIjp8L4iE4CAC4nGgrEx4K6mM0c88\nA/TrBzz2GPDWW+J1n33E991BqHEOXc2NN96Iv//976GWOXr0aMybN0+6/7777sN77723+7wrVqzA\nu+++i/feew/Dhg3Dli1bPH9XUVGBRx99FA8++CDKyzsi2/v164d3330Xjz32GB588EE89dRT2nXd\nvn073n77bWzYsAGTJk1CRUUFli5dik2bNmH16tVgZkyaNAkrV67E2LFjtcs1GHoTKtuBbUSeOjV1\nXywmOny3t1JBAbBkCfDpp8LGMHy4f5xDXR1w2WWpxmxm8f3kyULAdCU9WjjkCkcddVTabqFTrHnm\nkUceiRcDujKcddZZyMvLwyGHHIIvvvgCALB06VIsXboUhx9+OACgvr4emzZtMsLBkDV6esCXynbg\nZ0QeMwb
 47DNx/bqCwIvZs+VeTszArFnAr34VrMxM6dHCQTXC70pKHIrHgoICJJPJ3Z/9XEaj0SgA\nID8/39dmIfstIOIX7Nc77rgD06dPD1SWwZAOXn7+PS3gy7Yd2PEITnSMyEVF3jOLIPholLFxY+fP\nXSGQjc0hIH369MGuXbuk+/v3748vv/wStbW1aG5uxiuvvKL92zD4wQ9+gKeffhr11p2+bds2fPml\nV9C6wZAZ6erqcw2V7UDHiBwGo0ap948c2fE+HeN5OhjhEJC+ffviuOOOw6GHHopbb701ZX9hYSHm\nzJmDo446CieffDJGOf71Sy+9FFdffXUng3TYTJw4EVOnTsUxxxyDww47DBUVFVkXSAY5Qd0jexI6\nuvqegG07KCsTxuMgRuSwuPdecV4viMR+oIsFMjPn7HbkkUeymw8++CDlO0NwTDtmn9WrmcvKmONx\nZiLx

<TRUNCATED>


[10/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bd5a8f8d/examples/cifar10/predict.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/predict.py b/examples/cifar10/predict.py
index 123818a..7cab4b9 100644
--- a/examples/cifar10/predict.py
+++ b/examples/cifar10/predict.py
@@ -52,7 +52,7 @@ def predict(net, images, dev, topk=5):
 def load_dataset(filepath):
     print('Loading data file %s' % filepath)
     with open(filepath, 'rb') as fd:
-        cifar10 = pickle.load(fd)
+        cifar10 = pickle.load(fd, encoding='latin1')
     image = cifar10['data'].astype(dtype=np.uint8)
     image = image.reshape((-1, 3, 32, 32))
     label = np.asarray(cifar10['labels'], dtype=np.uint8)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bd5a8f8d/examples/cifar10/train.py
----------------------------------------------------------------------
diff --git a/examples/cifar10/train.py b/examples/cifar10/train.py
index 8204055..9f90e58 100644
--- a/examples/cifar10/train.py
+++ b/examples/cifar10/train.py
@@ -48,7 +48,7 @@ import resnet
 def load_dataset(filepath):
     print('Loading data file %s' % filepath)
     with open(filepath, 'rb') as fd:
-        cifar10 = pickle.load(fd)
+        cifar10 = pickle.load(fd, encoding='latin1')
     image = cifar10['data'].astype(dtype=np.uint8)
     image = image.reshape((-1, 3, 32, 32))
     label = np.asarray(cifar10['labels'], dtype=np.uint8)

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bd5a8f8d/python/singa/net.py
----------------------------------------------------------------------
diff --git a/python/singa/net.py b/python/singa/net.py
index c49b9fa..a53fc68 100644
--- a/python/singa/net.py
+++ b/python/singa/net.py
@@ -487,6 +487,7 @@ class FeedForwardNet(object):
                 f = f[0:-4]
             sp = snapshot.Snapshot(f, False, buffer_size)
             params = sp.read()
+        version = __version__
         if 'SINGA_VERSION' in params:
             version = params['SINGA_VERSION']
         for name, val in zip(self.param_names(), self.param_values()):

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bd5a8f8d/python/singa/snapshot.py
----------------------------------------------------------------------
diff --git a/python/singa/snapshot.py b/python/singa/snapshot.py
index 392ab3d..a4ac988 100644
--- a/python/singa/snapshot.py
+++ b/python/singa/snapshot.py
@@ -36,7 +36,6 @@ from builtins import object
 from . import singa_wrap as singa
 from . import tensor
 
-
 class Snapshot(object):
     ''' Class and member functions for singa::Snapshot.
 
@@ -58,7 +57,7 @@ class Snapshot(object):
             param_name (string): name of the parameter
             param_val (Tensor): value tensor of the parameter
         '''
-        self.snapshot.Write(str(param_name).encode(), param_val.singa_tensor)
+        self.snapshot.Write(param_name.encode(), param_val.singa_tensor)
 
     def read(self):
         '''Call read method to load all (param_name, param_val)


[11/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/bd5a8f8d/doc/en/docs/notebook/cnn.ipynb
----------------------------------------------------------------------
diff --git a/doc/en/docs/notebook/cnn.ipynb b/doc/en/docs/notebook/cnn.ipynb
index 64a3a25..d5198b2 100644
--- a/doc/en/docs/notebook/cnn.ipynb
+++ b/doc/en/docs/notebook/cnn.ipynb
@@ -24,20 +24,28 @@
    },
    "outputs": [],
    "source": [
-    "import cPickle, gzip\n",
+    "from __future__ import division\n",
+    "from builtins import zip\n",
+    "from builtins import str\n",
+    "from builtins import range\n",
+    "from past.utils import old_div\n",
+    "from future import standard_library\n",
+    "from __future__ import print_function\n",
+    "from tqdm import tnrange, tqdm_notebook\n",
+    "\n",
+    "standard_library.install_aliases()\n",
+    "import pickle, gzip\n",
     "\n",
     "# Load the dataset\n",
     "f = gzip.open('mnist.pkl.gz', 'rb')\n",
-    "train_set, valid_set, _ = cPickle.load(f)\n",
+    "train_set, valid_set, _ = pickle.load(f, encoding='latin1')\n",
     "f.close()"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 2,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
@@ -49,15 +57,15 @@
     }
    ],
    "source": [
-    "print train_set[0].shape, train_set[1].shape\n",
-    "print valid_set[0].shape, valid_set[1].shape"
+    "print(train_set[0].shape, train_set[1].shape)\n",
+    "print(valid_set[0].shape, valid_set[1].shape)"
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 3,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -70,14 +78,12 @@
   {
    "cell_type": "code",
    "execution_count": 4,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "<matplotlib.image.AxesImage at 0x7f0747e21410>"
+       "<matplotlib.image.AxesImage at 0x7fdde5663438>"
       ]
      },
      "execution_count": 4,
@@ -86,9 +92,9 @@
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADn9JREFUeJzt3X9sXfV5x/HPU8dxlhDauCmeSzMSIC3QsIbtKoCIgImR\npQgpoKqhUVWljDVdC3RsmQTLpjWb2JRNLVXKGJJZsyQVv0oLIn+wVmBV0GrgYbIQfpVfwV0TjE1w\nIYHSxLGf/eGTygXf73XuPfeeaz/vl2T53vOcc8+jk3x87r3fe8/X3F0A4vlA0Q0AKAbhB4Ii/EBQ\nhB8IivADQRF+ICjCDwRF+IGgCD8Q1IxG7mymtfkszWnkLoFQfq13dNgP2WTWrSn8ZrZS0mZJLZL+\nw903pdafpTk62y6qZZcAEnq8e9LrVv2038xaJN0i6dOSzpC0xszOqPbxADRWLa/5l0l6yd33uPth\nSXdJWpVPWwDqrZbwnyjpF+Pu782W/RYzW2dmvWbWO6xDNewOQJ7q/m6/u3e5e8ndS61qq/fuAExS\nLeHfJ2nBuPsfy5YBmAJqCf/jkhab2SIzmynpc5J25NMWgHqreqjP3Y+Y2TWSfqSxob4t7v5Mbp0B\nqKuaxvnd/QFJD+TUC4AG4uO9QFCEHwiK8ANBEX4gKMIPBEX4gaAIPxAU4QeCIvxAUIQfCIrwA0ER\nfiAowg8ERfiBoAg/EBThB4Ii/EBQhB8IivADQRF+ICjCDwRF+IGgCD8QFOEHgiL8QFCEHwiK8ANB\nEX4gKMIPBFXTLL1m1ifpoKQRSUfcvZRHU8iPzUj/E7d8ZH5d9//8Xy8sWxuZPZrc9qRTBpP12V+1\nZP21m2aWre0s3Z3cdv/IO8n62fesT9ZP/avHkvVmUFP4M3/k7vtzeBwADcTTfiCoWsPvkh4ysyfM\nbF0eDQFojFqf9i93931mdoKkB83sZ+7+yPgVsj8K6
 yRplmbXuDsAeanpzO/u+7Lfg5Luk7RsgnW6\n3L3k7qVWtdWyOwA5qjr8ZjbHzOYevS1phaSn82oMQH3V8rS/Q9J9Znb0ce5w9x/m0hWAuqs6/O6+\nR9Kncuxl2mo5fXGy7m2tyfqrF3woWX/3nPJj0u0fTI9X/+RT6fHuIv3Xr+Ym6//ybyuT9Z4z7yhb\ne2X43eS2mwYuTtY/+hNP1qcChvqAoAg/EBThB4Ii/EBQhB8IivADQeXxrb7wRi78g2T9pq23JOsf\nby3/1dPpbNhHkvW/v/mLyfqMd9LDbefec03Z2tx9R5Lbtu1PDwXO7u1J1qcCzvxAUIQfCIrwA0ER\nfiAowg8ERfiBoAg/EBTj/Dloe/7VZP2JXy9I1j/eOpBnO7la339Osr7n7fSlv7ee8v2ytbdG0+P0\nHd/+72S9nqb+F3Yr48wPBEX4gaAIPxAU4QeCIvxAUIQfCIrwA0GZe+NGNI+3dj/bLmrY/prF0JXn\nJusHVqYvr92y+7hk/cmv3nzMPR114/7fT9YfvyA9jj/y5lvJup9b/urufV9LbqpFa55Mr4D36fFu\nHfCh9NzlGc78QFCEHwiK8ANBEX4gKMIPBEX4gaAIPxBUxXF+M9si6VJJg+6+JFvWLuluSQsl9Ula\n7e6/rLSzqOP8lbTM/3CyPvLGULL+yh3lx+qfOX9Lcttl/3xtsn7CLcV9px7HLu9x/q2S3jsR+g2S\nut19saTu7D6AKaRi+N39EUnvPfWskrQtu71N0mU59wWgzqp9zd/h7v3Z7dckdeTUD4AGqfkNPx97\n06DsGwdmts7Mes2sd1iHat0dgJxUG/4BM+uUpOz3YLkV3b3L3UvuXmpVW5W7A5C3asO/Q9La7PZa\nSffn0w6ARqkYfjO7U9Kjkj5hZnvN7CpJmyRdbGYvSvrj7D6AKaTidfvdfU2ZEgP2ORnZ/0ZN2w8f\nmFn1tp/8/LPJ+uu3tqQfYHSk
 6n2jWHzCDwiK8ANBEX4gKMIPBEX4gaAIPxAUU3RPA6df/0LZ2pVn\npkdk//Ok7mT9gs9enazPvfuxZB3NizM/EBThB4Ii/EBQhB8IivADQRF+ICjCDwTFOP80kJom+42v\nnJ7c9v92vJus33Dj9mT9b1Zfnqz7/36wbG3BPz2a3FYNnD4+Is78QFCEHwiK8ANBEX4gKMIPBEX4\ngaAIPxBUxSm688QU3c1n6E/PTdZv//o3kvVFM2ZVve9Pbr8mWV98W3+yfmRPX9X7nq7ynqIbwDRE\n+IGgCD8QFOEHgiL8QFCEHwiK8ANBVRznN7Mtki6VNOjuS7JlGyV9SdLr2Wob3P2BSjtjnH/q8fOW\nJuvHb9qbrN958o+q3vdpP/6zZP0T/1D+OgaSNPLinqr3PVXlPc6/VdLKCZZ/y92XZj8Vgw+guVQM\nv7s/ImmoAb0AaKBaXvNfa2a7zWyLmc3LrSMADVFt+G+VdLKkpZL6JX2z3Ipmts7Mes2sd1iHqtwd\ngLxVFX53H3D3EXcflXSbpGWJdbvcveTupVa1VdsngJxVFX4z6xx393JJT+fTDoBGqXjpbjO7U9KF\nkuab2V5JX5d0oZktleSS+iR9uY49AqgDvs+PmrR0nJCsv3rFqWVrPddvTm77gQpPTD//yopk/a3l\nbyTr0xHf5wdQEeEHgiL8QFCEHwiK8ANBEX4gKIb6UJjv7U1P0T3bZibrv/LDyfql115X/rHv60lu\nO1Ux1AegIsIPBEX4gaAIPxAU4QeCIvxAUIQfCKri9/kR2+jy9KW7X/5seoruJUv7ytYqjeNXcvPQ\nWcn67Pt7a3r86Y4zPxAU4QeCIvxAUIQfCIrwA0ERfiAowg8ExTj/NGelJcn6C19Lj7Xfdt62ZP38\nWenv1NfikA8n648NLUo/wGh/jt1MP5z5gaAIPxAU4QeCIvxAUIQfCIrwA0ERfiCoiuP8ZrZA0nZJ\nHZJcUpe
 7bzazdkl3S1ooqU/Sanf/Zf1ajWvGopOS9Zev/GjZ2sYr7kpu+5nj9lfVUx42DJSS9Yc3\nn5Osz9uWvu4/0iZz5j8iab27nyHpHElXm9kZkm6Q1O3uiyV1Z/cBTBEVw+/u/e6+M7t9UNJzkk6U\ntErS0Y9/bZN0Wb2aBJC/Y3rNb2YLJZ0lqUdSh7sf/fzkaxp7WQBgiph0+M3sOEk/kHSdux8YX/Ox\nCf8mnPTPzNaZWa+Z9Q7rUE3NAsjPpMJvZq0aC/7t7n5vtnjAzDqzeqekwYm2dfcudy+5e6lVbXn0\nDCAHFcNvZibpO5Kec/ebxpV2SFqb3V4r6f782wNQL5P5Su95kr4g6Skz25Ut2yBpk6TvmdlVkn4u\naXV9Wpz6Ziz8vWT9rT/sTNav+McfJut//qF7k/V6Wt+fHo579N/LD+e1b/2f5LbzRhnKq6eK4Xf3\nn0oqN9/3Rfm2A6BR+IQfEBThB4Ii/EBQhB8IivADQRF+ICgu3T1JMzp/t2xtaMuc5LZfWfRwsr5m\n7kBVPeXhmn3Lk/Wdt6an6J7//aeT9faDjNU3K878QFCEHwiK8ANBEX4gKMIPBEX4gaAIPxBUmHH+\nw3+Svkz04b8cStY3nPpA2dqK33mnqp7yMjDybtna+TvWJ7c97e9+lqy3v5kepx9NVtHMOPMDQRF+\nICjCDwRF+IGgCD8QFOEHgiL8QFBhxvn7Lkv/nXvhzHvqtu9b3jwlWd/88Ipk3UbKXTl9zGk3vlK2\ntnigJ7ntSLKK6YwzPxAU4QeCIvxAUIQfCIrwA0ERfiAowg8EZe6eXsFsgaTtkjokuaQud99sZhsl\nfUnS69mqG9y9/JfeJR1v7X62Mas3UC893q0DPpT+YEhmMh/yOSJpvbvvNLO5kp4wswez2rfc/RvV\nNgqgOBXD7+79kvqz2wfN7DlJJ9a7MQD1dUyv+c1soaSzJB39zOi1ZrbbzLaY2bwy26wz
 s14z6x3W\noZqaBZCfSYffzI6T9ANJ17n7AUm3SjpZ0lKNPTP45kTbuXuXu5fcvdSqthxaBpCHSYXfzFo1Fvzb\n3f1eSXL3AXcfcfdRSbdJWla/NgHkrWL4zcwkfUfSc+5+07jlneNWu1xSerpWAE1lMu/2nyfpC5Ke\nMrNd2bINktaY2VKNDf/1SfpyXToEUBeTebf/p5ImGjdMjukDaG58wg8IivADQRF+ICjCDwRF+IGg\nCD8QFOEHgiL8QFCEHwiK8ANBEX4gKMIPBEX4gaAIPxBUxUt357ozs9cl/XzcovmS9jesgWPTrL01\na18SvVUrz95OcvePTGbFhob/fTs363X3UmENJDRrb83al0Rv1SqqN572A0ERfiCoosPfVfD+U5q1\nt2btS6K3ahXSW6Gv+QEUp+gzP4CCFBJ+M1tpZs+b2UtmdkMRPZRjZn1m9pSZ7TKz3oJ72WJmg2b2\n9Lhl7Wb2oJm9mP2ecJq0gnrbaGb7smO3y8wuKai3BWb2YzN71syeMbO/yJYXeuwSfRVy3Br+tN/M\nWiS9IOliSXslPS5pjbs/29BGyjCzPkkldy98TNjMzpf0tqTt7r4kW/avkobcfVP2h3Oeu1/fJL1t\nlPR20TM3ZxPKdI6fWVrSZZK+qAKPXaKv1SrguBVx5l8m6SV33+PuhyXdJWlVAX00PXd/RNLQexav\nkrQtu71NY/95Gq5Mb03B3fvdfWd2+6CkozNLF3rsEn0VoojwnyjpF+Pu71VzTfntkh4ysyfMbF3R\nzUygI5s2XZJek9RRZDMTqDhzcyO9Z2bppjl21cx4nTfe8Hu/5e6+VNKnJV2dPb1tSj72mq2Zhmsm\nNXNzo0wws/RvFHnsqp3xOm9FhH+fpAXj7n8sW9YU3H1f9ntQ0n1qvtmHB45Okpr9Hiy4n99oppmb\nJ5pZWk1w7Jppxusiwv+4pMVmtsjMZkr6nKQdBfTxPmY2J3sjRmY
 2R9IKNd/swzskrc1ur5V0f4G9\n/JZmmbm53MzSKvjYNd2M1+7e8B9Jl2jsHf+XJf1tET2U6etkSU9mP88U3ZukOzX2NHBYY++NXCXp\nw5K6Jb0o6SFJ7U3U23clPSVpt8aC1llQb8s19pR+t6Rd2c8lRR+7RF+FHDc+4QcExRt+QFCEHwiK\n8ANBEX4gKMIPBEX4gaAIPxAU4QeC+n8DZI6NXofNrQAAAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADoBJREFUeJzt3X2MXOV1x/HfyXq9jo1JvHHYboiLHeMEiGlMOjIgLKCi\nuA5CMiiKiRVFDiFxmuCktK4EdavGrWjlVgmRQynS0ri2I95CAsJ/0CR0FUGiwpbFMeYtvJlNY7Ps\nYjZgQ4i9Xp/+sdfRBnaeWc/cmTu75/uRVjtzz71zj6792zszz8x9zN0FIJ53Fd0AgGIQfiAowg8E\nRfiBoAg/EBThB4Ii/EBQhB8IivADQU1r5M6mW5vP0KxG7hII5bd6U4f9kE1k3ZrCb2YrJG2W1CLp\nP9x9U2r9GZqls+2iWnYJIKHHuye8btVP+82sRdJNkj4h6QxJq83sjGofD0Bj1fKaf6mk5919j7sf\nlnSHpJX5tAWg3moJ/8mSfjXm/t5s2e8xs7Vm1mtmvcM6VMPuAOSp7u/2u3uXu5fcvdSqtnrvDsAE\n1RL+fZLmjbn/wWwZgEmglvA/ImmRmS0ws+mSPi1pRz5tAai3qof63P2Ima2T9CONDvVtcfcnc+sM\nQF3VNM7v7vdJui+nXgA0EB/vBYIi/EBQhB8IivADQRF+ICjCDwRF+IGgCD8QFOEHgiL8QFCEHwiK\n8ANBEX4gKMIPBEX4gaAIPxAU4QeCIvxAUIQfCIrwA0ERfiAowg8ERfiBoAg/EBThB4Ii/EBQhB8I\nivADQRF+IKiaZuk1sz5JByWNSDri7qU8mkJ+bFr6n7jl/XPruv9n/np+2drIzKPJbU9ZOJisz/yK\nJesv3zC9bG1n6c7ktvtH3kzWz75rfbJ+6l89nKw3g5rCn/kTd9+fw+MAaCCe9gNB1Rp+l/RjM3vU\nzNbm0RCAxqj1af8yd99nZidJut/MfuHuD45dIfujs
 FaSZmhmjbsDkJeazvzuvi/7PSjpHklLx1mn\ny91L7l5qVVstuwOQo6rDb2azzGz2sduSlkt6Iq/GANRXLU/7OyTdY2bHHuc2d/9hLl0BqLuqw+/u\neyR9LMdepqyW0xcl697Wmqy/dMF7k/W3zik/Jt3+nvR49U8/lh7vLtJ//WZ2sv4v/7YiWe8587ay\ntReH30puu2ng4mT9Az/1ZH0yYKgPCIrwA0ERfiAowg8ERfiBoAg/EFQe3+oLb+TCjyfrN2y9KVn/\ncGv5r55OZcM+kqz//Y2fS9anvZkebjv3rnVla7P3HUlu27Y/PRQ4s7cnWZ8MOPMDQRF+ICjCDwRF\n+IGgCD8QFOEHgiL8QFCM8+eg7ZmXkvVHfzsvWf9w60Ce7eRqff85yfqeN9KX/t668Ptla68fTY/T\nd3z7f5L1epr8X9itjDM/EBThB4Ii/EBQhB8IivADQRF+ICjCDwRl7o0b0TzR2v1su6hh+2sWQ1ee\nm6wfWJG+vHbL7hOS9ce+cuNx93TM9fv/KFl/5IL0OP7Ia68n635u+au7930tuakWrH4svQLeoce7\ndcCH0nOXZzjzA0ERfiAowg8ERfiBoAg/EBThB4Ii/EBQFcf5zWyLpEslDbr74mxZu6Q7Jc2X1Cdp\nlbv/utLOoo7zV9Iy933J+sirQ8n6i7eVH6t/8vwtyW2X/vNXk/WTbiruO/U4fnmP82+V9PaJ0K+T\n1O3uiyR1Z/cBTCIVw+/uD0p6+6lnpaRt2e1tki7LuS8AdVbta/4Od+/Pbr8sqSOnfgA0SM1v+Pno\nmwZl3zgws7Vm1mtmvcM6VOvuAOSk2vAPmFmnJGW/B8ut6O5d7l5y91Kr2qrcHYC8VRv+HZLWZLfX\nSLo3n3YANErF8JvZ7ZIekvQRM9trZldJ2iTpYjN7TtKfZvcBTCIVr9vv7qvLlBiwz8nI/ldr2n74\nwPSqt/3oZ55K1l+5uSX9AEdH
 qt43isUn/ICgCD8QFOEHgiL8QFCEHwiK8ANBMUX3FHD6tc+WrV15\nZnpE9j9P6U7WL/jU1cn67DsfTtbRvDjzA0ERfiAowg8ERfiBoAg/EBThB4Ii/EBQjPNPAalpsl/9\n8unJbf9vx1vJ+nXXb0/W/2bV5cm6//w9ZWvz/umh5LZq4PTxEXHmB4Ii/EBQhB8IivADQRF+ICjC\nDwRF+IGgKk7RnSem6G4+Q58/N1m/9evfSNYXTJtR9b4/un1dsr7olv5k/cievqr3PVXlPUU3gCmI\n8ANBEX4gKMIPBEX4gaAIPxAU4QeCqjjOb2ZbJF0qadDdF2fLNkr6oqRXstU2uPt9lXbGOP/k4+ct\nSdZP3LQ3Wb/9Qz+qet+n/eQLyfpH/qH8dQwkaeS5PVXve7LKe5x/q6QV4yz/lrsvyX4qBh9Ac6kY\nfnd/UNJQA3oB0EC1vOZfZ2a7zWyLmc3JrSMADVFt+G+WtFDSEkn9kr5ZbkUzW2tmvWbWO6xDVe4O\nQN6qCr+7D7j7iLsflXSLpKWJdbvcveTupVa1VdsngJxVFX4z6xxz93JJT+TTDoBGqXjpbjO7XdKF\nkuaa2V5JX5d0oZktkeSS+iR9qY49AqgDvs+PmrR0nJSsv3TFqWVrPdduTm77rgpPTD/z4vJk/fVl\nrybrUxHf5wdQEeEHgiL8QFCEHwiK8ANBEX4gKIb6UJjv7U1P0T3Tpifrv/HDyfqlX72m/GPf05Pc\ndrJiqA9ARYQfCIrwA0ERfiAowg8ERfiBoAg/EFTF7/MjtqPL0pfufuFT6Sm6Fy/pK1urNI5fyY1D\nZyXrM+/trenxpzrO/EBQhB8IivADQRF+ICjCDwRF+IGgCD8QFOP8U5yVFifrz34tPdZ+y3nbkvXz\nZ6S/U1+LQz6crD88tCD9AEf7c+xm6uHMDwRF+IGgCD8QFOEHgiL8QFCEHwiK8ANBVRznN7N5krZL\n6pDkkrr
 cfbOZtUu6U9J8SX2SVrn7r+vXalzTFpySrL9w5QfK1jZecUdy20+esL+qnvKwYaCUrD+w\n+Zxkfc629HX/kTaRM/8RSevd/QxJ50i62szOkHSdpG53XySpO7sPYJKoGH5373f3ndntg5KelnSy\npJWSjn38a5uky+rVJID8HddrfjObL+ksST2SOtz92OcnX9boywIAk8SEw29mJ0j6gaRr3P3A2JqP\nTvg37qR/ZrbWzHrNrHdYh2pqFkB+JhR+M2vVaPBvdfe7s8UDZtaZ1TslDY63rbt3uXvJ3Uutasuj\nZwA5qBh+MzNJ35H0tLvfMKa0Q9Ka7PYaSffm3x6AepnIV3rPk/RZSY+b2a5s2QZJmyR9z8yukvRL\nSavq0+LkN23+Hybrr/9xZ7J+xT/+MFn/8/fenazX0/r+9HDcQ/9efjivfev/Jredc5ShvHqqGH53\n/5mkcvN9X5RvOwAahU/4AUERfiAowg8ERfiBoAg/EBThB4Li0t0TNK3zD8rWhrbMSm775QUPJOur\nZw9U1VMe1u1blqzvvDk9Rffc7z+RrLcfZKy+WXHmB4Ii/EBQhB8IivADQRF+ICjCDwRF+IGgwozz\nH/6z9GWiD//lULK+4dT7ytaWv/vNqnrKy8DIW2Vr5+9Yn9z2tL/7RbLe/lp6nP5osopmxpkfCIrw\nA0ERfiAowg8ERfiBoAg/EBThB4IKM87fd1n679yzZ95Vt33f9NrCZH3zA8uTdRspd+X0Uadd/2LZ\n2qKBnuS2I8kqpjLO/EBQhB8IivADQRF+ICjCDwRF+IGgCD8QlLl7egWzeZK2S+qQ5JK63H2zmW2U\n9EVJr2SrbnD38l96l3SitfvZxqzeQL30eLcO+FD6gyGZiXzI54ik9e6+08xmS3rUzO7Pat9y929U\n2yiA4lQMv7v3S+rPbh80s6clnVzvxgDU13G95jez+ZLOknTsM6PrzGy3mW0xszlltllr
 Zr1m1jus\nQzU1CyA/Ew6/mZ0g6QeSrnH3A5JulrRQ0hKNPjP45njbuXuXu5fcvdSqthxaBpCHCYXfzFo1Gvxb\n3f1uSXL3AXcfcfejkm6RtLR+bQLIW8Xwm5lJ+o6kp939hjHLO8esdrmk9HStAJrKRN7tP0/SZyU9\nbma7smUbJK02syUaHf7rk/SlunQIoC4m8m7/zySNN26YHNMH0Nz4hB8QFOEHgiL8QFCEHwiK8ANB\nEX4gKMIPBEX4gaAIPxAU4QeCIvxAUIQfCIrwA0ERfiCoipfuznVnZq9I+uWYRXMl7W9YA8enWXtr\n1r4keqtWnr2d4u7vn8iKDQ3/O3Zu1uvupcIaSGjW3pq1L4neqlVUbzztB4Ii/EBQRYe/q+D9pzRr\nb83al0Rv1Sqkt0Jf8wMoTtFnfgAFKST8ZrbCzJ4xs+fN7LoieijHzPrM7HEz22VmvQX3ssXMBs3s\niTHL2s3sfjN7Lvs97jRpBfW20cz2Zcdul5ldUlBv88zsJ2b2lJk9aWZ/kS0v9Ngl+irkuDX8ab+Z\ntUh6VtLFkvZKekTSand/qqGNlGFmfZJK7l74mLCZnS/pDUnb3X1xtuxfJQ25+6bsD+ccd7+2SXrb\nKOmNomduziaU6Rw7s7SkyyR9TgUeu0Rfq1TAcSvizL9U0vPuvsfdD0u6Q9LKAvpoeu7+oKShty1e\nKWlbdnubRv/zNFyZ3pqCu/e7+87s9kFJx2aWLvTYJfoqRBHhP1nSr8bc36vmmvLbJf3YzB41s7VF\nNzOOjmzadEl6WVJHkc2Mo+LMzY30tpmlm+bYVTPjdd54w++dlrn7xyV9QtLV2dPbpuSjr9maabhm\nQjM3N8o4M0v/TpHHrtoZr/NWRPj3SZo35v4Hs2VNwd33Zb8HJd2j5pt9eODYJKnZ78GC+/mdZpq5\nebyZpdUEx66ZZrwuIvyPSFpkZgvMbLqkT0vaUUAf72Bms7I3YmR
 msyQtV/PNPrxD0prs9hpJ9xbY\ny+9plpmby80srYKPXdPNeO3uDf+RdIlG3/F/QdLfFtFDmb4+JOmx7OfJonuTdLtGnwYOa/S9kask\nvU9St6TnJP23pPYm6u27kh6XtFujQessqLdlGn1Kv1vSruznkqKPXaKvQo4bn/ADguINPyAowg8E\nRfiBoAg/EBThB4Ii/EBQhB8IivADQf0/sEWOix6VKakAAAAASUVORK5CYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f077003c810>"
+       "<matplotlib.figure.Figure at 0x7fdde7991f60>"
       ]
      },
      "metadata": {},
@@ -113,27 +119,25 @@
   {
    "cell_type": "code",
    "execution_count": 5,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "conv1 (32, 14, 14)\n",
-      "relu1 (32, 14, 14)\n",
-      "conv2 (32, 7, 7)\n",
-      "relu2 (32, 7, 7)\n",
-      "pool (32, 4, 4)\n",
-      "flat (512,)\n",
-      "dense (10,)\n"
+      "('conv1', (32, 14, 14))\n",
+      "('relu1', (32, 14, 14))\n",
+      "('conv2', (32, 7, 7))\n",
+      "('relu2', (32, 7, 7))\n",
+      "('pool', (32, 4, 4))\n",
+      "('flat', (512,))\n",
+      "('dense', (10,))\n"
      ]
     },
     {
      "data": {
       "text/plain": [
-       "<singa.layer.Dense at 0x7f0735355990>"
+       "<singa.layer.Dense at 0x7fddc5ca3b00>"
       ]
      },
      "execution_count": 5,
@@ -154,7 +158,7 @@
     "net.add(Activation('relu2'))\n",
     "net.add(MaxPooling2D('pool', 3, 2))\n",
     "net.add(Flatten('flat'))\n",
-    "net.add(Dense('dense', 10))\n"
+    "net.add(Dense('dense', 10))"
    ]
   },
   {
@@ -170,20 +174,18 @@
   {
    "cell_type": "code",
    "execution_count": 6,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "conv1_weight (32, 9) 0.0764843672514\n",
-      "conv1_bias (32,) 0.0\n",
-      "conv2_weight (32, 288) 0.0803024768829\n",
-      "conv2_bias (32,) 0.0\n",
-      "dense_weight (512, 10) 0.0795410946012\n",
-      "dense_bias (10,) 0.0\n"
+      "conv1/weight (32, 9) 0.07648436725139618\n",
+      "conv1/bias (32,) 0.0\n",
+      "conv2/weight (32, 288) 0.08030246943235397\n",
+      "conv2/bias (32,) 0.0\n",
+      "dense/weight (512, 10) 0.07954108715057373\n",
+      "dense/bias (10,) 0.0\n"
      ]
     }
    ],
@@ -193,7 +195,7 @@
     "        pval.gaussian(0, 0.1)\n",
     "    else:\n",
     "        pval.set_value(0)\n",
-    "    print pname, pval.shape, pval.l1()"
+    "    print(pname, pval.shape, pval.l1())"
    ]
   },
   {
@@ -207,7 +209,7 @@
    "cell_type": "code",
    "execution_count": 7,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
@@ -219,7 +221,7 @@
     "\n",
     "opt = optimizer.SGD(momentum=0.9, weight_decay=1e-4)\n",
     "batch_size = 32\n",
-    "num_train_batch = train_x.shape[0] / batch_size\n",
+    "num_train_batch = old_div(train_x.shape[0], batch_size)\n",
     "\n",
     "tx = tensor.Tensor((batch_size, 1, 28, 28))\n",
     "ty = tensor.Tensor((batch_size,), cpu , tensor.int32)\n",
@@ -243,18 +245,40 @@
   {
    "cell_type": "code",
    "execution_count": 8,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "b9a8c3eff6744b90a2be87729cb60cd5"
+      }
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
      "name": "stdout",
      "output_type": "stream",
      "text": [
       "\n",
-      "Epoch = 0, training loss = 0.292792, training accuracy = 0.906530\n",
+      "Epoch = 0, training loss = 0.291366, training accuracy = 0.907370\n"
+     ]
+    },
+    {
+     "data": {
+      "application/vnd.jupyter.widget-view+json": {
+       "model_id": "4cca5a2fff6b47859adafae922ea20d9"
+      }
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
       "\n",
-      "Epoch = 1, training loss = 0.109958, training accuracy = 0.965589\n"
+      "Epoch = 1, training loss = 0.111163, training accuracy = 0.965089\n"
      ]
     }
    ],
@@ -276,7 +300,7 @@
     "            opt.apply_with_lr(epoch, 0.01, g, p, str(s), b)\n",
     "        # update progress bar\n",
     "        bar.set_postfix(train_loss=l, train_accuracy=a)\n",
-    "    print 'Epoch = %d, training loss = %f, training accuracy = %f' % (epoch, loss / num_train_batch, acc / num_train_batch)    \n"
+    "    print('Epoch = %d, training loss = %f, training accuracy = %f' % (epoch, old_div(loss, num_train_batch), old_div(acc, num_train_batch)))"
    ]
   },
   {
@@ -308,7 +332,6 @@
    "cell_type": "code",
    "execution_count": 10,
    "metadata": {
-    "collapsed": false,
     "scrolled": true
    },
    "outputs": [
@@ -316,13 +339,7 @@
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "NOTE: If your model was saved using pickle, then set use_pickle=True for loading it\n",
-      "conv2_bias\n",
-      "conv2_weight\n",
-      "dense_weight\n",
-      "conv1_bias\n",
-      "dense_bias\n",
-      "conv1_weight\n"
+      "NOTE: If your model was saved using pickle, then set use_pickle=True for loading it\n"
      ]
     }
    ],
@@ -343,14 +360,14 @@
    "cell_type": "code",
    "execution_count": 11,
    "metadata": {
-    "collapsed": false
+    "collapsed": true
    },
    "outputs": [],
    "source": [
     "from PIL import Image\n",
     "img = Image.open('static/digit.jpg').convert('L')\n",
     "img = img.resize((28,28))\n",
-    "img = np.array(img, dtype=np.float32)/255\n",
+    "img = old_div(np.array(img, dtype=np.float32),255)\n",
     "img = tensor.from_numpy(img)\n",
     "img.reshape((1,1,28,28))\n",
     "y=net.predict(img)"
@@ -359,14 +376,12 @@
   {
    "cell_type": "code",
    "execution_count": 12,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "[<matplotlib.lines.Line2D at 0x7f07356e4210>]"
+       "[<matplotlib.lines.Line2D at 0x7fddc4b29240>]"
       ]
      },
      "execution_count": 12,
@@ -375,9 +390,9 @@
     },
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG7pJREFUeJzt3WuMY+dZB/D/Y3s8F/vsbOZ2nJ29zG5iuyyX0HZIy0VQ\nKKVJC4RKICVcKipQiGigIKQ2IAEfyhdUQFARulqVghCIqGojCNXS9EOh/YBasoHSNEntmU72mswZ\nz+zteO62Hz7YZ9bjjMdnxsc+9jn/nxLtnOMzPs9a4/+cfc/j9xVVBRERBUvE7wKIiMh7DHciogBi\nuBMRBRDDnYgogBjuREQBxHAnIgoghjsRUQAx3ImIAojhTkQUQDG/TjwxMaEzMzN+nZ6IqC+9+OKL\ny6o62eo438J9ZmYGFy9e9Ov0RER9SUQuuzmOwzJERAHEcCciCiCGOxFRADHciYgCqGW4i8hnRGRJ\nRL7V5HERkU+KyLyIfFNE3uZ9mUREdBBurtz/HsBD+zz+MIB07f/HAXyq/bKIiKgdLcNdVb8K4MY+\nhzwC4B+06msAjorIvV4VSEREB+fFmPs0gKt129dq+4hCqVSu4Jn/voLtcsXvUijEunpDVUQeF5GL\nInKxUCh089REXfPVuQKeevYlfPnbS36XQiHmRbhfB3Cibvt4bd+bqOp5VZ1V1dnJyZafniXqS99e\ntAEA+dqfRH7wItyfA/DBWtfMOwHcVtU3PHheor7khHrOYriTf1rOLSMi/wzgXQAmROQagD8GMAAA\nqnoOwAUA7wMwD2ANwIc6VSxRP8hZRQBAnuFOPmoZ7qr6WIvHFcCHPauIqI+VyhV8Z6mIaESwUFjF\nVqmCeIyfFaTu408dkYcu31jDVrmCH7pvHKWK4tLKqt8lUUgx3Ik85Iy3/8wDxwAAOd5UJZ8w3Ik8\nlLNsiADvPZtCRDjuTv5huBN5KG/ZODU2gtGRAcxMJ
 HjlTr5huBN5KLdoI2MaAICsafDKnXzDcCfy\nyGapjEsra8imquGeMQ1cvrGGje2yz5VRGDHciTyyUFhFuaJ3r9xTBlSB+aWiz5VRGDHciTziDME4\n4Z4xkwDYMUP+YLgTeSS3aCMWEZyeSAAATo0nEI9GOO5OvmC4E3kkb9k4M5nY+UTqQDSCM5MJzjFD\nvmC4E3kkbxV3hmQc2ZSBOYtj7tR9DHciD6xtlXDlxhqyDeGeMQ1cv7UOe2Pbp8oorBjuRB5wrs7T\ne4Q7UL2qJ+omhjuRB5xxdafH3ZHdCXeOu1N3MdyJPDBn2RiMRXBybGTX/uP3DGN4IMpwp65juBN5\nIGcVkTaTiEZk1/5IRJAxkwx36jqGO5EH8nVzyjTKmAZyixxzp+5iuBO16fbaNhbvbOwb7svFTawU\nN7tcGYUZw52oTfml2s3UZuGeYscMdR/DnahNO3PKpPYOdyf055Y47k7dw3AnalN+0UZyMIZjo0N7\nPm4eGcSRoRgnEKOuYrgTtSln2ciYSYjIno+LCLIpLtxB3cVwJ2qDqu5afamZtGkgt2hDVbtUGYUd\nw52oDcvFLdxc224Z7lnTwJ2NEqw77Jih7mC4E7Vhrsm0A40ynIaAuozhTtSGXMPqS804qzIx3Klb\nGO5EbchbNsYScUwk4/seN54cxERykB0z1DUMd6I25BZtpKead8rU4xwz1E0Md6JDUlXMWcWW4+2O\njGkgbxVRqbBjhjqP4U50SG/c3oC9WWo53u7Ipgysb5dx/dZ6hysjYrgTHVqzBTqacX4JcNydusFV\nuIvIQyKSE5F5EXlqj8dHReTfROT/RORlEfmQ96US9ZZ8LaQzU27Dvdoxk+O4O3VBy3AXkSiApwE8\nDOAsgMdE5GzDYR8G8IqqPgDgXQD+XET2bx8g6nM5y4Z5ZBCjIwOujjeGBnBsdIg3Vakr3Fy5Pwhg\nXlUXVHULwDMAHmk4RgEYUm0Z
 SAK4AaDkaaVEPSZvtZ52oFEmZXBYhrrCTbhPA7hat32ttq/eXwP4\nLgCvA3gJwEdUteJJhUQ9qFxRzC8Vm87h3kzWNLBQWEWpzLcHdZZXN1TfC+AbAI4B+H4Afy0iRxoP\nEpHHReSiiFwsFAoenZqo+67eWMPGdqXpHO7NZEwDW+UKLq2sdagyoio34X4dwIm67eO1ffU+BOBZ\nrZoH8BqAtzQ+kaqeV9VZVZ2dnJw8bM1EvnM77UCjbIpzzFB3uAn3FwCkReR07SbpowCeazjmCoB3\nA4CImACyABa8LJSolzidMump5IG+777JJETYDkmdF2t1gKqWRORJAM8DiAL4jKq+LCJP1B4/B+Dj\nAP5eRF4CIAA+pqrLHaybyFc5y8aJsWEkBlu+hXYZjkdxamyEV+7Uca5+MlX1AoALDfvO1X39OoCf\n8rY0ot41Zx38ZqqjOg0Bw506i59QJTqgrVIF3ykUDzze7simDFxaWcPGdtnjyojuYrgTHdCllVWU\nKnrocM+YBsoVxUJh1ePKiO5iuBMdkHMztJ1wB9gxQ53FcCc6oLxlIxoRnJlMHOr7T08kEIsI55ih\njmK4Ex1Q3rIxMz6CoYHoob4/HovgzGRiZ/1Vok5guBMdUP4AC3Q0kzENXrlTRzHciQ5gY7uMSyur\nSLuc5reZrGng6o11rG5yfj3qDIY70QHMLxWh6n6BjmbStZuqc0tFL8oiehOGO9EBtNsp49iZY4bT\nEFCHMNyJDiC/ZCMejWBmfKSt5zk5NoLBWITtkNQxDHeiA8gv2rhvKolYtL23TjQiSJtJ3lSljmG4\nEx1A3irurIXaLs4xQ53EcCdyyd7YxvVb622PtzsypgHrziZurW158nxE9RjuRC7lrWpny2Fng2yU\n3ZmGgB0z5D2GO5FLzidK222DdGS4KhN1EMOdyKWcZWMkHsX00WFPnu/Y6BCSgzGGO3UEw53Ipbxl\nIz2VRCQ
 injyfiCBjJrnkHnUEw53Ipdzi4RfoaMbpmFFVT5+XiOFO5MKN1S0sFzc9G293ZEwDN9e2\nUShuevq8RAx3IheccXGvr9ydXxZz7JghjzHciVzIe9wp43B+WXDcnbzGcCdyIbdo48hQDFPGoKfP\nO5GMYywRZ8cMeY7hTuRC3rKRTRkQ8aZTxiEiSE9xjhnyHsOdqAVVrc0p4+2QjCObMjBnFdkxQ55i\nuBO1sGRv4vb6tufj7Y6MaaC4WcLrtzc68vwUTgx3oha8WqCjGS7cQZ3AcCdqoVNtkI5MbT1WjruT\nlxjuRC3kFm1MJAcxloh35PlHRwZgHhnklTt5iuFO1EJ+qYhsypsFOprJmAbySwx38g7DnWgflYpi\nzrI7NiTjyJrVjplyhR0z5A2GO9E+rt9ax9pW2bMFOprJpAxsliq4cmOto+eh8HAV7iLykIjkRGRe\nRJ5qcsy7ROQbIvKyiHzF2zKJ/OF0yqS7cOVefz6idrUMdxGJAngawMMAzgJ4TETONhxzFMDfAPhZ\nVf1uAL/QgVqJui630ynT2TH3+6eqz89pCMgrbq7cHwQwr6oLqroF4BkAjzQc84sAnlXVKwCgqkve\nlknkjznLxvTRYRhDAx09T2IwhhNjwwx38oybcJ8GcLVu+1ptX70MgHtE5D9F5EUR+eBeTyQij4vI\nRRG5WCgUDlcxURflrGLHr9od2drCHURe8OqGagzA2wG8H8B7AfyhiGQaD1LV86o6q6qzk5OTHp2a\nqDNK5Qq+s1TcWci60zKmgYXCKrZKla6cj4LNTbhfB3Cibvt4bV+9awCeV9VVVV0G8FUAD3hTIpE/\nLq2sYatc2fkEaadlUwZKFcVry6tdOR8Fm5twfwFAWkROi0gcwKMAnms45l8B/IiIxERkBMA7ALzq\nbalE3dWpBTqaSXMaAvJQrNUBqloSkScBPA8gCuAzqvqyiDxRe/ycqr4qIl8E8E0AFQCf
 VtVvdbJw\nok7LWzZE7naydNqZyQSiEcEcw5080DLcAUBVLwC40LDvXMP2JwB8wrvSiPyVt2zMjCcwNBDtyvmG\nBqKYGR9hrzt5gp9QJWoit2gj3aWrdkc2xY4Z8gbDnWgPG9tlXFpZ69p4uyNjGrh8Yw3rW+WunpeC\nh+FOtIeFwirKFe34hGGNsqYBVWB+qdjV81LwMNyJ9jC31N1OGYczhw2HZqhdDHeiPeQWbQxEBTPj\nia6ed2Z8BPFohOFObWO4E+0hb9k4PZFAPNbdt0gsGsF9U0n2ulPbGO5Ee8h1YYGOZrJmkkvuUdsY\n7kQNVjdLuHpjveMLdDSTSRl4/fYG7mxs+3J+CgaGO1EDp1OlWxOGNXLmspmz2DFDh8dwJ2rgjHf7\ndeXudOjwpiq1g+FO1CC/aGMwFsGJsRFfzj99dBgj8SinIaC2MNyJGuQsG2kziWhEfDl/JCJIc+EO\nahPDnahB3sdOGUfWTDLcqS0Md6I6t9e2Yd3Z9G283ZExDSwXt7BS3PS1DupfDHeiOvnatAN+dco4\nMjvTELBjhg6H4U5Ux7mJ6fuwDDtmqE0Md6I6ectGcjCGY6NDvtYxZQxidHiA0xDQoTHcierkFm1k\nzCRE/OmUcYgIsqbBaQjo0BjuRDWqirxld32a32bStY4ZVfW7FOpDDHeimuXiFm6ubfs+3u7Ipgzc\n2SjBusOOGTo4hjtRjXPzslfC3amD4+50GAx3oppe6ZRx7LRDctydDoHhTlSTt2yMJeKYSMb9LgUA\nMJaIY9IY5JU7HQrDnaimOu2A/50y9TJmEnMMdzoEhjsRnE6Zou/TDjTKmAbyVhGVCjtm6GAY7kQA\nXr+9geJmCekeC/esaWB9u4xrN9f9LoX6DMOdCHdvWvZKj7vDmeOG4+50UAx3ItS1QU71Vrinp5IA\nOMcMHRzDnQjVK+PUkSGMjgz4XcouxtAApo8OM9zpwBjuRKh1yvT
 YkIwjYya55B4dmKtwF5GHRCQn\nIvMi8tQ+x/2AiJRE5Oe9K5Gos8oVxZxVRKY2BNJrMikDC4VVbJcrfpdCfaRluItIFMDTAB4GcBbA\nYyJytslxfwrgS14XSdRJV26sYbNU6dkr96xpYKtcweWVVb9LoT7i5sr9QQDzqrqgqlsAngHwyB7H\n/RaAzwNY8rA+oo5zxrN7rcfdwVWZ6DDchPs0gKt129dq+3aIyDSADwD4lHelEXWH0waZNntzWOb+\nqSQiAo6704F4dUP1LwF8TFX3HRQUkcdF5KKIXCwUCh6dmqg9OcvGybERjMRjfpeyp6GBKE6NJ9gx\nQwfi5qf5OoATddvHa/vqzQJ4pjYnxwSA94lISVX/pf4gVT0P4DwAzM7O8vPU1BOcOWV6WcZM8oNM\ndCBurtxfAJAWkdMiEgfwKIDn6g9Q1dOqOqOqMwA+B+A3G4OdqBdtlSpYKKz2zDS/zWRNA5eWV7Gx\nXfa7FOoTLcNdVUsAngTwPIBXAXxWVV8WkSdE5IlOF0jUSZdWVlGqaM9NO9AokzJQUWChwI4ZcsfV\nIKOqXgBwoWHfuSbH/mr7ZRF1R68t0NHM3Y4ZG2ePHfG5GuoH/IQqhVreshGNCM5MJvwuZV8z4wkM\nRIXj7uQaw51CLbdoY2Z8BIOxqN+l7Csei+DMRJJL7pFrDHcKtbxl9/x4uyOTMnjlTq4x3Cm0NrbL\nuHxjrefH2x1ZM4lrN9exulnyuxTqAwx3Cq35pSJUe3fagUbOKlFzS5yGgFpjuFNo5XamHeiPcHd+\nCXHcndxguFNo5S0b8WgEM+MjfpfiyomxEQwNRDjuTq4w3Cm0cpaN+6aSiEX7420QjQjSUwbnmCFX\n+uOnmqgD5qwisj0+p0yjjMlwJ3cY7hRK9sY2rt9a79kFOprJmElYdzZxa23L71KoxzHcKZSchS8y\nU30W7iku3EHuMNwplHZWX+qzK3enY4Y3Va
 kVhjuFUm7Rxkg8iumjw36XciD3jg7BGIyxHZJaYrhT\nKM0t2UibBiIR8buUAxERZFK8qUqtMdwplHKL/dcp48iYSeQtG6pczIyaY7hT6KwUN7Fc3OybOWUa\nZUwDN9e2UShu+l0K9TCGO4XOTqdMn4b73WkI2DFDzTHcKXT6tVPG4bRDsmOG9sNwp9DJWzZGhwcw\nZQz6XcqhTCQHMZ6IY47hTvtguFPo5C0bWdOASH91ytRLm0leudO+GO4UKqqK3KKNdJ92yjiypoH8\nIjtmqDmGO4WKdWcTdzZKfTve7sikDKxulXH91rrfpVCPYrhTqDhDGf3aKePY6Zjh0Aw1wXCnUJkL\nSLinTU4gRvtjuFOo5BZtTBqDGEvE/S6lLaPDA0gdGeIcM9QUw51CJW/ZyPT5zVRHJmWwY4aaYrhT\naFQqirxV7PshGUfWTGJuqYhyhR0z9GYMdwqNazfXsb5d3rkZ2e8ypoGtUgWXV1b9LoV6EMOdQsPp\nLOm3pfWayXJVJtoHw51CwxmfTk8FY8z9/trfg+2QtBeGO4VG3rIxfXQYxtCA36V4YiQew8mxEd5U\npT25CncReUhEciIyLyJP7fH4L4nIN0XkJRH5LxF5wPtSidqTWwxOp4wjU5uGgKhRy3AXkSiApwE8\nDOAsgMdE5GzDYa8B+DFV/V4AHwdw3utCidpRKlewUFgNzHi7I5tK4rXlVWyVKn6XQj3GzZX7gwDm\nVXVBVbcAPAPgkfoDVPW/VPVmbfNrAI57WyZRey6trGGrXAlMp4wjYxooVRSvLbNjhnZzE+7TAK7W\nbV+r7Wvm1wD8+14PiMjjInJRRC4WCgX3VRK1KR+QaQcaOX8fjrtTI09vqIrIj6Ma7h/b63FVPa+q\ns6o6Ozk56eWpifaVW7QRkbsdJkFxZjKBaEQ47k5vEnNxzHUAJ+q2j9f27SIi3wfg0wAeVtUVb8oj\n8kbesnFqPIGhgajfp
 XhqMBbF6YkEr9zpTdxcub8AIC0ip0UkDuBRAM/VHyAiJwE8C+BXVDXvfZlE\n7QnSnDKNsqbBJffoTVqGu6qWADwJ4HkArwL4rKq+LCJPiMgTtcP+CMA4gL8RkW+IyMWOVUx0QBvb\nZVxaWQvczVRHxjRw+cYa1rfKfpdCPcTNsAxU9QKACw37ztV9/esAft3b0oi8sVBYRbmigWuDdGTM\nJFSB+aUivvf4qN/lUI/gJ1Qp8ILaKeNwfmlx3J3qMdwp8HKWjYGoYGY84XcpHXFqbATxWIRzzNAu\nDHcKvDnLxpmJJOKxYP64x6IR3D+ZZLjTLsH8aSeqk7PswI63O7IpzjFDuzHcKdBWN0u4emMd2YC2\nQTrSZhKv397AnY1tv0uhHsFwp0CbW6ouZJEO6M1Uh9PmyX53cjDcKdCcoYqg9rg7duaYWeSqTFTF\ncKdAy1s2hgYiODE24ncpHTV9dBiJeJQ3VWkHw50CLWfZSE8ZiEbE71I6KhIRpE2D4U47GO4UaNU5\nZYI9JOPImGyHpLsY7hRYt9a2YN3ZDOyEYY0ypoHl4haWi5t+l0I9gOFOgZW3qjcXg97j7sjW/p68\neieA4U4B5oRc0DtlHHfbIdkxQwx3CrC8ZcMYjOHe0SG/S+mKSWMQR0cGOIEYAWC4U4DlFm2kzSRE\ngt0p4xARZKY4DQFVMdwpkFQVecveGYcOi0wqiZxlQ1X9LoV8xnCnQCoUN3FzbTs0bZCOrGnA3ihh\n8c6G36WQzxjuFEjOTcWw3Ex1OL/M8rypGnoMdwqkXG3cOSxtkI6dcOe4e+gx3CmQ8paNsUQcE8lB\nv0vpqnsScUwag+yYIYY7BVPOskPzydRGWc4xQ2C4UwCpKuasYujG2x0Z08CcVUSlwo6ZMGO4U+C8\nfnsDxc1S6MbbHdlUEuvbZVy7ue53KeQjhjsFTlgW6GhmZ+EODs2EGsOdAscJtaAvrddM2uQEYsRw\n
 pwDKL9pIHRnC6PCA36X4IjkYw/TR4Z12UAonhjsFTs6yQzve7sim2DETdgx3CpRyRTG/VEQ2pG2Q\njoxpYKGwiu1yxe9SyCcMdwqUKzfWsFmqhG5OmUbZVBJb5Qour6z6XQr5hOFOgbIz7UDIwz09VeuY\nWeQcM2HlKtxF5CERyYnIvIg8tcfjIiKfrD3+TRF5m/elErWW3+mUCfewzP1TSUSE7ZBh1jLcRSQK\n4GkADwM4C+AxETnbcNjDANK1/x8H8CmP6yRyJWfZODk2gpF4zO9SfDU0EMXMeIITiIWYmyv3BwHM\nq+qCqm4BeAbAIw3HPALgH7TqawCOisi9HtdK1NKcZYd+SMaRMQ3klxjuYeXm8mYawNW67WsA3uHi\nmGkAb7RV3R6+ki/gT77witdP29fanUGkl1btaXdJvIVCEe85a3pUTX/LpAw8/8oi3vMXX/G7lJ6g\nqP6sa22jflsVUCgqteaixv1af/xe39vs6ybf+xs/egYffegtHf37dvXfriLyOKrDNjh58uShniM5\nGAv9eOpeBG2uE9oLy4x68Dvmu+49gg+8dbr9JwqAn/v+Y7i0vIpShe2QDoGg9h9EpPZndTsizmOy\ns0/qt6XJftQ/1nDMzjl273/w9HjH/65uwv06gBN128dr+w56DFT1PIDzADA7O3uot/LbT92Dt596\n+2G+lShUzkwm8cnH3up3GeQTN2PuLwBIi8hpEYkDeBTAcw3HPAfgg7WumXcCuK2qng/JEBGROy2v\n3FW1JCJPAngeQBTAZ1T1ZRF5ovb4OQAXALwPwDyANQAf6lzJRETUiqsxd1W9gGqA1+87V/e1Aviw\nt6UREdFh8ROqREQBxHAnIgoghjsRUQAx3ImIAojhTkQUQOLXR89FpADg8iG/fQLAsofl9Du+Hrvx\n9biLr8VuQXg9TqnqZKuDfAv3dojIRVWd9buOXsHXYze+HnfxtdgtTK8Hh2WIi
 AKI4U5EFED9Gu7n\n/S6gx/D12I2vx118LXYLzevRl2PuRES0v369cicion30Xbi3Wqw7TETkhIj8h4i8IiIvi8hH/K7J\nbyISFZH/FZEv+F2L30TkqIh8TkS+LSKvisgP+l2TX0Tkd2vvkW+JyD+LyJDfNXVaX4W7y8W6w6QE\n4PdU9SyAdwL4cMhfDwD4CIBX/S6iR/wVgC+q6lsAPICQvi4iMg3gtwHMqur3oDp1+aP+VtV5fRXu\ncLdYd2io6huq+j+1r21U37yhXWNORI4DeD+AT/tdi99EZBTAjwL4WwBQ1S1VveVvVb6KARgWkRiA\nEQCv+1xPx/VbuDdbiDv0RGQGwFsBfN3fSnz1lwA+CoCLhgKnARQA/F1tmOrTIpLwuyg/qOp1AH8G\n4AqAN1BdKe5L/lbVef0W7rQHEUkC+DyA31HVO37X4wcR+WkAS6r6ot+19IgYgLcB+JSqvhXAKoBQ\n3qMSkXtQ/Rf+aQDHACRE5Jf9rarz+i3cXS3EHSYiMoBqsP+Tqj7rdz0++mEAPysil1AdrvsJEflH\nf0vy1TUA11TV+Zfc51AN+zD6SQCvqWpBVbcBPAvgh3yuqeP6LdzdLNYdGiIiqI6pvqqqf+F3PX5S\n1d9X1eOqOoPqz8WXVTXwV2fNqOoigKsikq3tejeAV3wsyU9XALxTREZq75l3IwQ3l12todormi3W\n7XNZfvphAL8C4CUR+UZt3x/U1rwl+i0A/1S7EFpASBeuV9Wvi8jnAPwPqh1m/4sQfFKVn1AlIgqg\nfhuWISIiFxjuREQBxHAnIgoghjsRUQAx3ImIAojhTkQUQAx3IqIAYrgTEQXQ/wNXckf+AMbmGAAA\nAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXcAAAD8CAYAAACMwORRAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAG7xJREFUeJzt3WtsY2d+3/Hvn9RtJNJzk4Zaz4xnxrbIZjZIuhvBu80C\n7aLrBva2tV+0KWw0vQSL+E2cbppFCqct3MJ9labYXgA3rZOmadNkHa+7KAbptA7QbNug6C483k22\nazuk5PHYM7MjSnM1KY2u/PcFeTQaWhdKOuQhz/l9AMMidYb8gxj99Mzz/M/zmLsjIiLxkoq6ABER\nCZ/CXUQkhhTuIiIxpHAXEYkhhbuISAwp3EVEYkjhLiISQwp3EZEYUriLiMRQX1RvPDo66qdPn47q\n7UVEetJbb7113d3HdrousnA/ffo0Fy5ciOrtRUR6kpl90Mp1mpYREYkhhbuISAwp3EVEYkjhLiIS\nQwp3EZEY2jHczew3zGzWzL6/xffNzP6VmU2b2ffM7NPhlykiIrvRysj9N4Entvn+k8BE47/ngF/d\nf1kiIrIfO4a7u/9v4OY2lzwN/Eev+xZwyMw+EVaBIr2murTK1y9cRkdYSpTCmHM/Dlze8PhK47mP\nMbPnzOyCmV2Ym5sL4a1Fus83vnOFX3z9e7xz7aOoS5EE6+iCqru/4u6T7j45Nrbj3bMiPelPZioA\nlMqViCuRJAsj3K8CJzc8PtF4TiSRSo1wL85UI65EkiyMcD8H/M1G18xngTvufi2E1xXpOe5OsayR\nu0Rvx43DzOxrwOeBUTO7AvwjoB/A3f8NcB74IjANLAA/3a5iRbrdzEeLVBZXSaeM4ozCXaKzY7i7\n+7M7fN+Bnw2tIpEeVirXp2J+/JGj/OHUdapLq2QGI9t8VRJMd6iKhCiYb//LP/IgAFOampGIKNxF\nQlQsVxjLDvLYmSOA5t0lOgp3kRCVyhUKuSwnjwwz1
 J9Sx4xERuEuEpJazZkqV8nnsqRTxsSxrEbu\nEhmFu0hIrty6y92VNQrjGQDyOYW7REfhLhKSoL89n8sCUBjPMFtZ4tb8cpRlSUIp3EVCEozSJxrh\nHvxfo3eJgsJdJCTFmQrHDx1Y72svKNwlQgp3kZCUyhUK49n1x584OER2sG99ukakkxTuIiFYWatx\ncW5+fb4dwMzIj2fX71oV6SSFu0gIPrgxz/Jabb1TJhB0zOjgDuk0hbtICIKblSaOZe97Pp/LcHth\nhbnKUhRlSYIp3EVCUCxXSBk8euz+kXuwqKp5d+k0hbtICKbKFU4fHWGoP33f8/nxoGNG8+7SWQp3\nkRAUy5X7FlMDo5lBjo4MrO8WKdIpCneRfVpcWePS9fn1UXqzfC6raRnpOIW7yD69N1el5vXF083k\ncxmmyhVqNXXMSOco3EX2KbgDtbDJtAzU593nl9e4evtuJ8uShFO4i+xTqVylP22cHh3Z9PtB6E/N\nampGOkfhLrJPpZkKj4xl6E9v/uMUbCCmgzukkxTuIvu0VadM4OCBfj5xcEgbiElHKdxF9qG6tMqV\nW3e3XEwNTOSyFNUOKR2kcBfZh6mmAzq2UshlmJ6rsqaOGekQhbvIPkw17jwtbNHjHsjnsiyv1vjg\nxnwnyhJRuIvsR7FcYag/xcnDw9teVxjXwR3SWQp3kX0oNRZTUynb9rpHj2UwU8eMdI7CXWQfijOV\nj23zu5nhgT5OHh7WyF06RuEuske3F5aZrSx97ICOrWiPGekkhbvIHgXb+O7UKRMojGe4dH2epdW1\ndpYlAijcRfYsGIXv1CkTyOeyrNac96+rY0bar6VwN7MnzKxoZtNm9sIm33/IzL5pZt81s++Z2RfD\nL1Wku5RmKmQH+xh/YKil64NfArqZSTphx3A3szTwMvAkcBZ41szONl32D4HX3P1TwDPAvw67UJFu\nUyxXyI9nMdu+UyZwZnSEdMq0
 qCod0crI/TFg2t0vuvsy8CrwdNM1DjzQ+Pog8IPwShTpPu6+3gbZ\nqsG+NGdGR9QOKR3R18I1x4HLGx5fAT7TdM0/Bn7fzH4OGAEeD6U6kS41V13i9sIKhR32lGlWyGX5\n/g/utKkqkXvCWlB9FvhNdz8BfBH4LTP72Gub2XNmdsHMLszNzYX01iKdV2qMvrc6Wm8r+VyWD28u\nsLC82o6yRNa1Eu5XgZMbHp9oPLfRl4DXANz9/wJDwGjzC7n7K+4+6e6TY2Nje6tYpAsUW9wwrFlh\nPIM7TM9qakbaq5VwfxOYMLMzZjZAfcH0XNM1HwJfADCzH6Ie7hqaS2yVZiocHRlgNDO4qz937+AO\nLapKe+0Y7u6+CjwPvAG8S70r5m0ze8nMnmpc9hXgZ8zsj4GvAX/b3bW3qcTWTgd0bOXUkWEG+lLq\nmJG2a2VBFXc/D5xveu7FDV+/A3wu3NJEupO7M1Wu8JOTJ3e+uElfOsWjY5n1u1tF2kV3qIrs0tXb\nd5lfXtvTyB3qNzNp5C7tpnAX2aXS+mLq7togA/lclmt3FrlzdyXMskTuo3AX2aXgJqSJPY7cg18K\nUxq9Sxsp3EV2qVSu8ImDQxw80L+nPx9M52j7X2knhbvILu1224Fmxw8dYGQgvX7+qkg7KNxFdmGt\n5kzNVlve5nczqZQxkcuq113aSuEusgsf3JhnebXGxLG9LaYGCjl1zEh7KdxFdqG0ywM6tjKRy3Bj\nfpnr1aUwyhL5GIW7yC4UZ6qYwaP7Hbk3fjmUNDUjbaJwF9mF0myFh44MMzzQ0s3dWyo0FmQ1NSPt\nonAX2YXSzP46ZQJj2UEODfdTVMeMtInCXaRFS6trvH99fs93pm5kZuS1qCptpHAXadH71+dZrXko\nI3eo36lamqmgDVSlHRTuIi0K+tL32ykTKOSyVJZWuXZnMZTXE9lI4S7Soqlylb6U8fDo/qdl4N42\nBJqakXZ
 QuIu0qFiucGZ0hIG+cH5sFO7STgp3kRbtd0+ZZodHBjiWHVzfZVIkTAp3kRYsLK/y4c2F\nUMMdUMeMtI3CXaQF07NV3KEwHs58eyCfyzI1W6FWU8eMhEvhLtKC4MzTsEfuhfEMiys1Lt9aCPV1\nRRTuIi0olSsM9KU4dXQk1NddP7hDe8xIyBTuIi0ozlR4dCxDOmWhvu6EOmakTRTuIi0olSuh3by0\nUWawj+OHDmiPGQmdwl1kBx8trnDtzmLo8+2BwnhWh2VL6BTuIjuYWj+gI9xOmUA+l+W9uSora7W2\nvL4kk8JdZAfBTUbtG7lnWFlzLl2fb8vrSzIp3EV2UCpXGBlIc/zQgba8/nrHjKZmJEQKd5EdFGcq\nTOSymIXbKRN4ZCxDynTknoRL4S6yg6nZyvqxeO0w1J/m9NGR9RulRMKgcBfZxvXqEtery+Tb0Aa5\nkfaYkbAp3EW2EQRuO0fuAPnxLJduzLO4stbW95HkaCnczewJMyua2bSZvbDFNX/NzN4xs7fN7HfC\nLVMkGsE8eBjnpm6nkMtS8/oGZSJh2DHczSwNvAw8CZwFnjWzs03XTAC/BHzO3T8J/HwbahXpuGK5\nyqHhfsayg219n+CXh6ZmJCytjNwfA6bd/aK7LwOvAk83XfMzwMvufgvA3WfDLVMkGlONAzra1SkT\nOD06Qn/atKgqoWkl3I8Dlzc8vtJ4bqM8kDez/2Nm3zKzJzZ7ITN7zswumNmFubm5vVUs0iHuTrHc\n3k6ZQH86xSNjGY3cJTRhLaj2ARPA54FngV8zs0PNF7n7K+4+6e6TY2NjIb21SHvMfLRIZXG17Z0y\ngXwuq61/JTSthPtV4OSGxycaz210BTjn7ivu/j5Qoh72Ij0rCNr8sfYupgYK41mu3r5LZXGlI+8n\n8dZKuL8JTJjZGTMbAJ4BzjVd81+oj9oxs1Hq0zQXQ6xTpOOCKZJ27SnTbKLxS2RKHTMS
 gh3D3d1X\ngeeBN4B3gdfc/W0ze8nMnmpc9gZww8zeAb4J/KK732hX0SKdUCpXOZYd5PDIQEfeL9gvXtv/Shj6\nWrnI3c8D55uee3HD1w78QuM/kVho1wEdWzl5eJih/tT6LpQi+6E7VEU2Uas5pXKFiWOdC/dUyrQN\ngYRG4S6yicu3FlhcqbXtgI6t5HNZbf0roVC4i2xivVOmQ4upgUIuy1xliVvzyx19X4kfhbvIJoKO\nlYkOh/uEtiGQkCjcRTZRnKlw4vABMoMt9RyEJljAVbjLfincRTZRauwp02njDwyRHerTvLvsm8Jd\npMnKWo335qqRhLuZUchlKakdUvZJ4S7S5NL1eVbWvOOdMoH8eL1jpn77iMjeKNxFmgTb7kYxcof6\nXjZ37q4wV1mK5P0lHhTuIk2K5Qopg0fGohu5B3WI7JXCXaRJaabC6aMjDPWnI3n/YP94bf8r+6Fw\nF2kSVadM4GhmkNHMgNohZV8U7iIbLK6scenGfMcO6NhKfRsCdczI3incRTZ4b65KzenI0Xrbyeey\nTJcr1GrqmJG9UbiLbBBMhUTVBhnI57LML69x9fbdSOuQ3qVwF9mgOFOlP22cOjoSaR3BLxfNu8te\nKdxFNiiVKzwylqE/He2PRrBhmdohZa8U7iIbFGei7ZQJPDDUz4MHhyipHVL2SOEu0lBdWuXq7bsd\nPVpvOxO57PrdsiK7pXAXaQgOpu6GkTvUt/+dnquyulaLuhTpQQp3kYbSerhH2ykTyOeyLK/W+ODm\nQtSlSA9SuIs0FGeqDPWnOHl4OOpSgHu99pp3l71QuIs0BNsOpFIWdSkAPHosg5k6ZmRvFO4iDVHv\nKdPswECah44MM6VFVdkDhbsIcGt+mdnKUuTbDjSr7zGjkbvsnsJdhHuLqRNdspgaKOSyvH99nqXV\ntahLkR6jcBdh454yXTZyH8+yVnMuzs1HXYr0GIW7CPWj9bJDfYw
 /MBR1KfdZ75jR1IzsksJdhHpH\nSiGXxaw7OmUCZ0ZH6EuZwl12TeEuiefu9U6ZLpuSARjoS3FmdITijDpmZHdaCncze8LMimY2bWYv\nbHPdXzEzN7PJ8EoUaa+5yhK3F1bIH+uuxdRAfjyrkbvs2o7hbmZp4GXgSeAs8KyZnd3kuizwZeDb\nYRcp0k5Bq2E3jtyhPu/+4c0FFpZXoy5FekgrI/fHgGl3v+juy8CrwNObXPdPgF8GFkOsT6Ttgp0X\nu63HPRDcWDU9q6kZaV0r4X4cuLzh8ZXGc+vM7NPASXf/ryHWJtIRpZkKo5kBjmYGoy5lU8FGZkXt\nMSO7sO8FVTNLAV8FvtLCtc+Z2QUzuzA3N7fftxYJRbHLth1oduroCAN9Kc27y660Eu5XgZMbHp9o\nPBfIAj8M/E8zuwR8Fji32aKqu7/i7pPuPjk2Nrb3qkVCUqs5U10e7umUMXEsQ1F7zMgutBLubwIT\nZnbGzAaAZ4BzwTfd/Y67j7r7aXc/DXwLeMrdL7SlYpEQXb19l/nlta4Od6ivB2jrX9mNHcPd3VeB\n54E3gHeB19z9bTN7ycyeaneBIu00NRtsO9CdbZCB/HiWmY8WuXN3JepSpEf0tXKRu58Hzjc99+IW\n135+/2WJdEZwc9BEl4/cg0XVqXKFydNHIq5GeoHuUJVEK5UrPHhwiAeG+qMuZVvBtJG2/5VWKdwl\n0Yozla4ftQMcP3SAkYG05t2lZQp3Say1mjM9V+26bX43Y2bkx3Vwh7RO4S6J9cGNeZZXa13fKRMo\n5LI6ck9apnCXxFo/oKNHwn0il+XG/DLXq0tRlyI9QOEuiVWcqWIGj3bpbpDN1g/u0Ly7tEDhLolV\nKld46MgwBwbSUZfSknyjF1/z7tIKhbskVrfvKdNsLDPI4eF+7TEjLVG4SyItra5x6fp8z8y3Q6Nj\nJpdd36JYZDsKd0mk96/Ps1rzrj2gYyv5xh
 4z7h51KdLlFO6SSMHe6MFt/b0iP56lsrTKtTs6E0e2\np3CXRCqVK/SljIdHeyvcC9qGQFqkcJdEKs5UOTNaPwSjlwT/0lA7pOykt/5mi4RkarbSc/PtAIeG\nB8g9MKhFVdmRwl0SZ2F5lQ9vLvRUp8xG9Y4Zjdxlewp3SZzp2SruvbeYGsjnskzNVlirqWNGtqZw\nl8S51ynTmyP3Qi7L4kqNyzcXoi5FupjCXRKnVK4w0Jfi1NGRqEvZk2CtQB0zsh2FuyROqVxl4liG\ndMqiLmVPJo7dO3JPZCsKd0mcUrnSs4upACODfZw4fICiOmZkGwp3SZQ7d1e4dmexJ47W206hsQ2B\nyFYU7pIowVRGYbw3O2UC+fEs781VWV6tRV2KdCmFuyRKsAjZq50ygUIuy2rNuXRjPupSpEsp3CVR\npspVRgbSHD90IOpS9iX45aSbmWQrCndJlOJMfdsBs97slAk8PDZCyrTHjGxN4S6JUipXyB/r7SkZ\ngKH+NKdHR9TrLltSuEtiXK8ucWN+uSc3DNtMQacyyTYU7pIYwRRGL/e4b5TPZbl0Y57FlbWoS5Eu\npHCXxAgWH/M93gYZKIxnca9vhCbSTOEuiVEsVzk83M9YZjDqUkKxfnCH5t1lEwp3SYxSucJErvc7\nZQKnjo4wkE5pUVU21VK4m9kTZlY0s2kze2GT7/+Cmb1jZt8zs/9hZqfCL1Vk79yd0kxv7ynTrD+d\n4uGxEbVDyqZ2DHczSwMvA08CZ4Fnzexs02XfBSbd/UeA14F/GnahIvtx7c4ilaXV2HTKBArj6piR\nzbUycn8MmHb3i+6+DLwKPL3xAnf/prsHJwd8CzgRbpki+xPMS8dp5A71jpmrt+9SWVyJuhTpMq2E\n+3Hg8obHVxrPbeVLwH/b7Btm9pyZXTCzC3Nzc61XKbJP650yPXq03laCbQim1DEjTUJdUDWznwIm\ngV/Z7Pvu/oq7T7r75
 NjYWJhvLbKt4kyVY9lBDg0PRF1KqIJ/iWjeXZr1tXDNVeDkhscnGs/dx8we\nB/4B8OfcfSmc8kTCUSpXKMRsvh3gxOEDHOhPq2NGPqaVkfubwISZnTGzAeAZ4NzGC8zsU8C/BZ5y\n99nwyxTZu1rNmZqt9Pw2v5tJpYx8LsOUFlWlyY7h7u6rwPPAG8C7wGvu/raZvWRmTzUu+xUgA3zd\nzP7IzM5t8XIiHXf51gKLK7XYLaYG8rmsRu7yMa1My+Du54HzTc+9uOHrx0OuSyQ0xZlg24H4hvvX\n37rCzflljozEa01B9k53qErsBZ0yE8fi1SkTCH5paRsC2UjhLrFXLFc5cfgAI4Mt/UO15xR0KpNs\nQuEusTdVjte2A81yDwzywFCfwl3uo3CXWFtZq/HeXDW28+0AZlbfhmBGHTNyj8JdYu3S9XlW1jzW\nI3eAiUbHjLtHXYp0CYW7xFrQIjgRs20HmhVyWe7cXWG2ovsHpU7hLrFWmqmQMnhkLN7hHtygVdQ2\nBNKgcJdYK5WrnB4dYag/HXUpbaVTmaSZwl1irRTzTpnA0cwgo5lBhbusU7hLbC2urHHpxnws95TZ\nTD6Xoag9ZqRB4S6xNT1bpeYkKNyzTJUr1GrqmBGFu8TY+ulL4/FeTA0UxrMsLK9x9fbdqEuRLqBw\nl9gqlasMpFOcOjoSdSkdkdc2BLKBwl1iq1Su8PDYCP3pZPw1DzpmtP2vgMJdYqw4E88DOraSHern\nwYNDOnJPAIW7xFRlcYWrt+/G8mi97eTHs+qYEUDhLjE1NVsPuCSN3KG+DcF7s1VW12pRlyIRU7hL\nLE0FnTIJC/d8LsvyWo0Pbi5EXYpETOEusVScqXKgP82JwweiLqWjgmkozbuLwl1iqVSuMJHLkEpZ\n1KV01CNjGczUMSMKd4mpYjlZnTKBAwNpTh0ZVq+7KNwlfm7NLzNXWUrcfHsgn8tq619RuEv8BKPW\n
 OB+tt53CeJZLNxZYWl2LuhSJkMJdYqeU0E6ZQD6XZa3mXJybj7oUiZDCXWKnWK6QHeoj98Bg1KVE\nQnvMCCjcJYZKM1UKuSxmyeqUCZwZHaEvZZp3TziFu8SKu9c7ZRI63w4w0Jfi4bERjdwTTuEusTJX\nWeLO3ZXEzrcH8rksJe0xk2gKd4mV4OadJPa4b1TIZfnw5gILy6tRlyIRUbhLrATzzMHe5kk10fjl\nNqXRe2K1FO5m9oSZFc1s2sxe2OT7g2b2u43vf9vMToddqEgrSuUKo5kBjmaS2SkTCPaY0TYEybVj\nuJtZGngZeBI4CzxrZmebLvsScMvdHwX+OfDLYRcq0opiuZr4KRmAh44MM9iX0gZiCdbKyP0xYNrd\nL7r7MvAq8HTTNU8D/6Hx9evAFyypfWgSmVrNmU7onjLN0iljIpehNKtpmaTqa+Ga48DlDY+vAJ/Z\n6hp3XzWzO8BR4HoYRW702puX+bU/vBj2y/Ysj7qALlJzZ355LXGnL20ln8vye398jb/w1f8VdSld\nIayfFff9v9KXH8/z1I8+GEI1W2sl3ENjZs8BzwE89NBDe3qNQ8P9TCR8sayZoX8kBf70iUN84YeO\nRV1GV/jrnznF0motlDCKi9B+Vvb5MoeH+8OpYxuthPtV4OSGxycaz212zRUz6wMOAjeaX8jdXwFe\nAZicnNzT37if+OQ4P/HJ8b38UZFE+bFTh/mxU4ejLkMi0sqc+5vAhJmdMbMB4BngXNM154C/1fj6\nrwJ/4BouiIhEZseRe2MO/XngDSAN/Ia7v21mLwEX3P0c8O+A3zKzaeAm9V8AIiISkZbm3N39PHC+\n6bkXN3y9CPxkuKWJiMhe6Q5VEZEYUriLiMSQwl1EJIYU7iIiMaRwFxGJIYuqHd3M5oAP9vjHR2nD\n1gY9TJ/H/fR53KPP4n5x+DxOufvYThdFFu77YWYX3H0y6jq6hT6P++nzuEefx
 f2S9HloWkZEJIYU\n7iIiMdSr4f5K1AV0GX0e99PncY8+i/sl5vPoyTl3ERHZXq+O3EVEZBs9F+47HdadFGZ20sy+aWbv\nmNnbZvblqGvqBmaWNrPvmtnvRV1L1MzskJm9bmZ/YmbvmtmfibqmqJjZ3238nHzfzL5mZkNR19Ru\nPRXuLR7WnRSrwFfc/SzwWeBnE/xZbPRl4N2oi+gS/xL47+7+p4AfJaGfi5kdB/4OMOnuP0x96/LY\nb0veU+FOa4d1J4K7X3P37zS+rlD/wT0ebVXRMrMTwF8Efj3qWqJmZgeBP0v9rAXcfdndb0dbVaT6\ngAONk+KGgR9EXE/b9Vq4b3ZYd6IDDcDMTgOfAr4dbSWR+xfA3wNqURfSBc4Ac8C/b0xT/bqZjURd\nVBTc/Srwz4APgWvAHXf//Wirar9eC3dpYmYZ4D8DP+/uH0VdT1TM7C8Bs+7+VtS1dIk+4NPAr7r7\np4B5IJFrVGZ2mPq/8M8ADwIjZvZT0VbVfr0W7q0c1p0YZtZPPdh/292/EXU9Efsc8JSZXaI+Xffn\nzew/RVtSpK4AV9w9+Nfc69TDPokeB9539zl3XwG+Afx4xDW1Xa+FeyuHdSeCmRn1+dR33f2rUdcT\nNXf/JXc/4e6nqf+9+AN3j/3obCvuPgNcNrNC46kvAO9EWFKUPgQ+a2bDjZ+bL5CAxeWWzlDtFlsd\n1h1xWVH5HPA3gP9nZn/UeO7vN867FQH4OeC3GwOhi8BPR1xPJNz922b2OvAd6l1m3yUBd6rqDlUR\nkRjqtWkZERFpgcJdRCSGFO4iIjGkcBcRiSGFu4hIDCncRURiSOEuIhJDCncRkRj6/5J3/U/FAH0D\nAAAAAElFTkSuQmCC\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f0747e45890>"
+       "<matplotlib.figure.Figure at 0x7fdde5663da0>"
       ]
      },
      "metadata": {},
@@ -386,7 +401,7 @@
    ],
    "source": [
     "prob=tensor.to_numpy(y)[0]\n",
-    "plt.plot(range(10), prob)"
+    "plt.plot(list(range(10)), prob)"
    ]
   },
   {
@@ -405,270 +420,268 @@
   {
    "cell_type": "code",
    "execution_count": 13,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "conv1_weight (32, 9) 7.97165679932\n",
-      "conv1_bias (32,) 0.0\n",
-      "conv2_weight (32, 288) 8.00566577911\n",
-      "conv2_bias (32,) 0.0\n",
-      "dense_weight (512, 10) 7.92119693756\n",
-      "dense_bias (10,) 0.0\n",
+      "conv1/weight (32, 9) 7.971656799316406\n",
+      "conv1/bias (32,) 0.0\n",
+      "conv2/weight (32, 288) 8.005664825439453\n",
+      "conv2/bias (32,) 0.0\n",
+      "dense/weight (512, 10) 7.921195983886719\n",
+      "dense/bias (10,) 0.0\n",
       "\n",
       "\n",
       "Epoch 0\n",
-      "-->conv1: 3.886751\n",
-      "conv1-->relu1: 2.299547\n",
-      "relu1-->conv2: 603.797852\n",
-      "conv2-->relu2: 295.446167\n",
-      "relu2-->pool: 955.442017\n",
-      "pool-->flat: 955.442017\n",
-      "flat-->dense: 284901.062500\n",
-      "-->dense: 0.311904\n",
-      "dense-->flat: 0.311904\n",
-      "flat-->pool: 0.086828\n",
-      "pool-->relu2: 0.050518\n",
-      "relu2-->conv2: 9.024708\n",
-      "conv2-->relu1: 2.790344\n",
-      "relu1-->conv1: 336.182007\n",
-      "\n",
-      " loss = 79.148743, params\n",
-      "conv1_weight 10.1786603928\n",
-      "conv1_bias 12.2705039978\n",
-      "conv2_weight 8.05525493622\n",
-      "conv2_bias 0.13293106854\n",
-      "dense_weight 8.18883609772\n",
-      "dense_bias 0.00134002871346\n",
+      "-->conv1: 4.059905\n",
+      "conv1-->relu1: 2.407956\n",
+      "relu1-->conv2: 620.319519\n",
+      "conv2-->relu2: 302.810760\n",
+      "relu2-->pool: 965.994873\n",
+      "pool-->flat: 965.994873\n",
+      "flat-->dense: 276680.062500\n",
+      "-->dense: 0.270273\n",
+      "dense-->flat: 0.270273\n",
+      "flat-->pool: 0.074453\n",
+      "pool-->relu2: 0.046011\n",
+      "relu2-->conv2: 8.166893\n",
+      "conv2-->relu1: 2.553801\n",
+      "relu1-->conv1: 299.891296\n",
+      "\n",
+      " loss = 68.231674, params\n",
+      "conv1/weight 9.855006217956543\n",
+      "conv1/bias 9.832422256469727\n",
+      "conv2/weight 8.0507173538208\n",
+      "conv2/bias 0.1285100281238556\n",
+      "dense/weight 8.218809127807617\n",
+      "dense/bias 0.0013595324708148837\n",
       "\n",
       "\n",
       "Epoch 1\n",
-      "-->conv1: 20.362625\n",
-      "conv1-->relu1: 4.780766\n",
-      "relu1-->conv2: 2066.139404\n",
-      "conv2-->relu2: 488.272614\n",
-      "relu2-->pool: 1144.980225\n",
-      "pool-->flat: 1144.980225\n",
-      "flat-->dense: 1392742.250000\n",
-      "-->dense: 0.286131\n",
-      "dense-->flat: 0.286131\n",
-      "flat-->pool: 0.084796\n",
-      "pool-->relu2: 0.034586\n",
-      "relu2-->conv2: 7.695237\n",
-      "conv2-->relu1: 2.117975\n",
-      "relu1-->conv1: 487.341522\n",
-      "\n",
-      " loss = 70.960945, params\n",
-      "conv1_weight 16.7161483765\n",
-      "conv1_bias 34.0985298157\n",
-      "conv2_weight 8.74045848846\n",
-      "conv2_bias 0.33584010601\n",
-      "dense_weight 9.48363685608\n",
-      "dense_bias 0.00340566551313\n",
+      "-->conv1: 17.634811\n",
+      "conv1-->relu1: 3.629616\n",
+      "relu1-->conv2: 1683.136475\n",
+      "conv2-->relu2: 389.035248\n",
+      "relu2-->pool: 934.496582\n",
+      "pool-->flat: 934.496582\n",
+      "flat-->dense: 1198527.500000\n",
+      "-->dense: 0.322575\n",
+      "dense-->flat: 0.322575\n",
+      "flat-->pool: 0.094647\n",
+      "pool-->relu2: 0.039437\n",
+      "relu2-->conv2: 8.781067\n",
+      "conv2-->relu1: 2.430810\n",
+      "relu1-->conv1: 502.457764\n",
+      "\n",
+      " loss = 79.148743, params\n",
+      "conv1/weight 14.95351791381836\n",
+      "conv1/bias 28.66775131225586\n",
+      "conv2/weight 8.543733596801758\n",
+      "conv2/bias 0.320060670375824\n",
+      "dense/weight 9.1849365234375\n",
+      "dense/bias 0.0028705699369311333\n",
       "\n",
       "\n",
       "Epoch 2\n",
-      "-->conv1: 52.302490\n",
-      "conv1-->relu1: 10.072969\n",
-      "relu1-->conv2: 12706.870117\n",
-      "conv2-->relu2: 1381.310059\n",
-      "relu2-->pool: 1888.169067\n",
-      "pool-->flat: 1888.169067\n",
-      "flat-->dense: 4740897.500000\n",
-      "-->dense: 0.350905\n",
-      "dense-->flat: 0.350905\n",
-      "flat-->pool: 0.111108\n",
-      "pool-->relu2: 0.023244\n",
-      "relu2-->conv2: 7.156909\n",
-      "conv2-->relu1: 1.548402\n",
-      "relu1-->conv1: 516.079651\n",
-      "\n",
-      " loss = 73.690216, params\n",
-      "conv1_weight 30.0410804749\n",
-      "conv1_bias 60.256187439\n",
-      "conv2_weight 11.2280254364\n",
-      "conv2_bias 0.536676049232\n",
-      "dense_weight 13.0333833694\n",
-      "dense_bias 0.00553257204592\n",
+      "-->conv1: 44.400776\n",
+      "conv1-->relu1: 8.777474\n",
+      "relu1-->conv2: 12810.666016\n",
+      "conv2-->relu2: 1705.242798\n",
+      "relu2-->pool: 2268.597656\n",
+      "pool-->flat: 2268.597656\n",
+      "flat-->dense: 4815859.500000\n",
+      "-->dense: 0.347976\n",
+      "dense-->flat: 0.347976\n",
+      "flat-->pool: 0.109863\n",
+      "pool-->relu2: 0.024067\n",
+      "relu2-->conv2: 7.023767\n",
+      "conv2-->relu1: 1.075155\n",
+      "relu1-->conv1: 418.399963\n",
+      "\n",
+      " loss = 76.419479, params\n",
+      "conv1/weight 29.47024154663086\n",
+      "conv1/bias 52.10609436035156\n",
+      "conv2/weight 10.518251419067383\n",
+      "conv2/bias 0.5825839042663574\n",
+      "dense/weight 12.961698532104492\n",
+      "dense/bias 0.004623417742550373\n",
       "\n",
       "\n",
       "Epoch 3\n",
-      "-->conv1: 96.670937\n",
-      "conv1-->relu1: 2.220010\n",
-      "relu1-->conv2: 16051.786133\n",
-      "conv2-->relu2: 705.551208\n",
-      "relu2-->pool: 846.462280\n",
-      "pool-->flat: 846.462280\n",
-      "flat-->dense: 4615773.000000\n",
-      "-->dense: 0.454912\n",
-      "dense-->flat: 0.454912\n",
-      "flat-->pool: 0.146553\n",
-      "pool-->relu2: 0.012394\n",
-      "relu2-->conv2: 6.071361\n",
-      "conv2-->relu1: 0.411632\n",
-      "relu1-->conv1: 328.999054\n",
-      "\n",
-      " loss = 81.878014, params\n",
-      "conv1_weight 44.8700485229\n",
-      "conv1_bias 111.767730713\n",
-      "conv2_weight 14.0987415314\n",
-      "conv2_bias 0.919560790062\n",
-      "dense_weight 18.0457553864\n",
-      "dense_bias 0.00845981575549\n",
+      "-->conv1: 82.561668\n",
+      "conv1-->relu1: 2.029232\n",
+      "relu1-->conv2: 19918.304688\n",
+      "conv2-->relu2: 2221.255859\n",
+      "relu2-->pool: 3186.028076\n",
+      "pool-->flat: 3186.028076\n",
+      "flat-->dense: 8799418.000000\n",
+      "-->dense: 0.585852\n",
+      "dense-->flat: 0.585852\n",
+      "flat-->pool: 0.186150\n",
+      "pool-->relu2: 0.025595\n",
+      "relu2-->conv2: 10.546330\n",
+      "conv2-->relu1: 1.008846\n",
+      "relu1-->conv1: 2478.874512\n",
+      "\n",
+      " loss = 87.336548, params\n",
+      "conv1/weight 45.3760871887207\n",
+      "conv1/bias 122.97279357910156\n",
+      "conv2/weight 12.587639808654785\n",
+      "conv2/bias 0.9543725252151489\n",
+      "dense/weight 21.757226943969727\n",
+      "dense/bias 0.007790021598339081\n",
       "\n",
       "\n",
       "Epoch 4\n",
-      "-->conv1: 165.898941\n",
-      "conv1-->relu1: 0.000018\n",
-      "relu1-->conv2: 1.004575\n",
-      "conv2-->relu2: 0.049885\n",
-      "relu2-->pool: 0.214831\n",
-      "pool-->flat: 0.214831\n",
-      "flat-->dense: 1963.049194\n",
-      "-->dense: 0.560196\n",
-      "dense-->flat: 0.560196\n",
-      "flat-->pool: 0.182800\n",
-      "pool-->relu2: 0.026711\n",
-      "relu2-->conv2: 10.339769\n",
-      "conv2-->relu1: 0.006092\n",
-      "relu1-->conv1: 11.064970\n",
-      "\n",
-      " loss = 45.199768, params\n",
-      "conv1_weight 58.6796875\n",
-      "conv1_bias 162.814819336\n",
-      "conv2_weight 16.8376598358\n",
-      "conv2_bias 1.47756028175\n",
-      "dense_weight 23.0595436096\n",
-      "dense_bias 0.01112665236\n",
+      "-->conv1: 181.790573\n",
+      "conv1-->relu1: 0.000030\n",
+      "relu1-->conv2: 1.017071\n",
+      "conv2-->relu2: 0.120676\n",
+      "relu2-->pool: 0.305297\n",
+      "pool-->flat: 0.305297\n",
+      "flat-->dense: 2401.528809\n",
+      "-->dense: 0.703576\n",
+      "dense-->flat: 0.703576\n",
+      "flat-->pool: 0.229087\n",
+      "pool-->relu2: 0.029813\n",
+      "relu2-->conv2: 13.549859\n",
+      "conv2-->relu1: 0.006924\n",
+      "relu1-->conv1: 4.986567\n",
+      "\n",
+      " loss = 68.686081, params\n",
+      "conv1/weight 59.74170684814453\n",
+      "conv1/bias 191.91458129882812\n",
+      "conv2/weight 14.60444450378418\n",
+      "conv2/bias 1.4008562564849854\n",
+      "dense/weight 30.463171005249023\n",
+      "dense/bias 0.010233680717647076\n",
       "\n",
       "\n",
       "Epoch 5\n",
-      "-->conv1: 241.562866\n",
+      "-->conv1: 260.486359\n",
       "conv1-->relu1: 0.000000\n",
-      "relu1-->conv2: 1.477560\n",
-      "conv2-->relu2: 0.000000\n",
-      "relu2-->pool: 0.000000\n",
-      "pool-->flat: 0.000000\n",
-      "flat-->dense: 0.011127\n",
-      "-->dense: 0.668576\n",
-      "dense-->flat: 0.668576\n",
-      "flat-->pool: 0.218311\n",
-      "pool-->relu2: 0.000000\n",
-      "relu2-->conv2: 0.000000\n",
+      "relu1-->conv2: 1.400860\n",
+      "conv2-->relu2: 0.062520\n",
+      "relu2-->pool: 0.062520\n",
+      "pool-->flat: 0.062520\n",
+      "flat-->dense: 296.831329\n",
+      "-->dense: 2.126958\n",
+      "dense-->flat: 2.126958\n",
+      "flat-->pool: 0.694517\n",
+      "pool-->relu2: 0.014730\n",
+      "relu2-->conv2: 6.709585\n",
       "conv2-->relu1: 0.000000\n",
       "relu1-->conv1: 0.000000\n",
       "\n",
-      " loss = 2.299366, params\n",
-      "conv1_weight 71.2618331909\n",
-      "conv1_bias 208.757034302\n",
-      "conv2_weight 19.3444824219\n",
-      "conv2_bias 2.00746393204\n",
-      "dense_weight 27.6571712494\n",
-      "dense_bias 0.0137531962246\n",
+      " loss = 65.246483, params\n",
+      "conv1/weight 72.80561828613281\n",
+      "conv1/bias 253.96200561523438\n",
+      "conv2/weight 16.481393814086914\n",
+      "conv2/bias 1.8957630395889282\n",
+      "dense/weight 38.40126419067383\n",
+      "dense/bias 0.014084763824939728\n",
       "\n",
       "\n",
       "Epoch 6\n",
-      "-->conv1: 296.653534\n",
+      "-->conv1: 347.085114\n",
       "conv1-->relu1: 0.000000\n",
-      "relu1-->conv2: 2.007464\n",
-      "conv2-->relu2: 0.000000\n",
-      "relu2-->pool: 0.000000\n",
-      "pool-->flat: 0.000000\n",
-      "flat-->dense: 0.013753\n",
-      "-->dense: 0.910015\n",
-      "dense-->flat: 0.910015\n",
-      "flat-->pool: 0.297148\n",
-      "pool-->relu2: 0.000000\n",
-      "relu2-->conv2: 0.000000\n",
+      "relu1-->conv2: 1.895745\n",
+      "conv2-->relu2: 0.013967\n",
+      "relu2-->pool: 0.013967\n",
+      "pool-->flat: 0.013967\n",
+      "flat-->dense: 33.670372\n",
+      "-->dense: 1.395184\n",
+      "dense-->flat: 1.395184\n",
+      "flat-->pool: 0.455570\n",
+      "pool-->relu2: 0.009508\n",
+      "relu2-->conv2: 3.835509\n",
       "conv2-->relu1: 0.000000\n",
       "relu1-->conv1: 0.000000\n",
       "\n",
-      " loss = 2.301979, params\n",
-      "conv1_weight 82.6378097534\n",
-      "conv1_bias 250.104797363\n",
-      "conv2_weight 21.6229515076\n",
-      "conv2_bias 2.484375\n",
-      "dense_weight 31.8290367126\n",
-      "dense_bias 0.0165074821562\n",
+      " loss = 38.581238, params\n",
+      "conv1/weight 84.56834411621094\n",
+      "conv1/bias 309.804443359375\n",
+      "conv2/weight 18.20405387878418\n",
+      "conv2/bias 2.4867684841156006\n",
+      "dense/weight 45.590518951416016\n",
+      "dense/bias 0.016868162900209427\n",
       "\n",
       "\n",
       "Epoch 7\n",
-      "-->conv1: 348.356262\n",
+      "-->conv1: 416.296112\n",
       "conv1-->relu1: 0.000000\n",
-      "relu1-->conv2: 2.484375\n",
+      "relu1-->conv2: 2.486759\n",
       "conv2-->relu2: 0.000000\n",
       "relu2-->pool: 0.000000\n",
       "pool-->flat: 0.000000\n",
-      "flat-->dense: 0.016507\n",
-      "-->dense: 0.927903\n",
-      "dense-->flat: 0.927903\n",
-      "flat-->pool: 0.302989\n",
+      "flat-->dense: 0.016868\n",
+      "-->dense: 1.538023\n",
+      "dense-->flat: 1.538023\n",
+      "flat-->pool: 0.502211\n",
       "pool-->relu2: 0.000000\n",
       "relu2-->conv2: 0.000000\n",
       "conv2-->relu1: 0.000000\n",
       "relu1-->conv1: 0.000000\n",
       "\n",
-      " loss = 2.302492, params\n",
-      "conv1_weight 92.8762283325\n",
-      "conv1_bias 287.317565918\n",
-      "conv2_weight 23.6872882843\n",
-      "conv2_bias 2.9135928154\n",
-      "dense_weight 35.6038131714\n",
-      "dense_bias 0.0192515775561\n",
+      " loss = 2.308411, params\n",
+      "conv1/weight 95.16199493408203\n",
+      "conv1/bias 360.06231689453125\n",
+      "conv2/weight 19.77170753479004\n",
+      "conv2/bias 3.043811798095703\n",
+      "dense/weight 52.087501525878906\n",
+      "dense/bias 0.01910635642707348\n",
       "\n",
       "\n",
       "Epoch 8\n",
-      "-->conv1: 394.178162\n",
+      "-->conv1: 469.519379\n",
       "conv1-->relu1: 0.000000\n",
-      "relu1-->conv2: 2.913593\n",
+      "relu1-->conv2: 3.043824\n",
       "conv2-->relu2: 0.000000\n",
       "relu2-->pool: 0.000000\n",
       "pool-->flat: 0.000000\n",
-      "flat-->dense: 0.019252\n",
-      "-->dense: 1.218609\n",
-      "dense-->flat: 1.218609\n",
-      "flat-->pool: 0.397913\n",
+      "flat-->dense: 0.019106\n",
+      "-->dense: 1.641877\n",
+      "dense-->flat: 1.641877\n",
+      "flat-->pool: 0.536123\n",
       "pool-->relu2: 0.000000\n",
       "relu2-->conv2: 0.000000\n",
       "conv2-->relu1: 0.000000\n",
       "relu1-->conv1: 0.000000\n",
       "\n",
-      " loss = 2.300582, params\n",
-      "conv1_weight 102.090713501\n",
-      "conv1_bias 320.808746338\n",
-      "conv2_weight 25.5548191071\n",
-      "conv2_bias 3.29988527298\n",
-      "dense_weight 39.0138893127\n",
-      "dense_bias 0.0218270029873\n",
+      " loss = 2.301430, params\n",
+      "conv1/weight 104.70797729492188\n",
+      "conv1/bias 405.2940368652344\n",
+      "conv2/weight 21.199617385864258\n",
+      "conv2/bias 3.545147657394409\n",
+      "dense/weight 57.95866775512695\n",
+      "dense/bias 0.02116413414478302\n",
       "\n",
       "\n",
       "Epoch 9\n",
-      "-->conv1: 430.156555\n",
+      "-->conv1: 525.609802\n",
       "conv1-->relu1: 0.000000\n",
-      "relu1-->conv2: 3.299885\n",
+      "relu1-->conv2: 3.545132\n",
       "conv2-->relu2: 0.000000\n",
       "relu2-->pool: 0.000000\n",
       "pool-->flat: 0.000000\n",
-      "flat-->dense: 0.021827\n",
-      "-->dense: 1.221773\n",
-      "dense-->flat: 1.221773\n",
-      "flat-->pool: 0.398946\n",
+      "flat-->dense: 0.021164\n",
+      "-->dense: 2.182356\n",
+      "dense-->flat: 2.182356\n",
+      "flat-->pool: 0.712606\n",
       "pool-->relu2: 0.000000\n",
       "relu2-->conv2: 0.000000\n",
       "conv2-->relu1: 0.000000\n",
       "relu1-->conv1: 0.000000\n",
       "\n",
-      " loss = 2.302244, params\n",
-      "conv1_weight 110.383636475\n",
-      "conv1_bias 350.950500488\n",
-      "conv2_weight 27.2405776978\n",
-      "conv2_bias 3.64754581451\n",
-      "dense_weight 42.0904846191\n",
-      "dense_bias 0.0241855494678\n"
+      " loss = 2.316046, params\n",
+      "conv1/weight 113.30311584472656\n",
+      "conv1/bias 446.00213623046875\n",
+      "conv2/weight 22.49642562866211\n",
+      "conv2/bias 3.9963467121124268\n",
+      "dense/weight 63.25651931762695\n",
+      "dense/bias 0.02255747839808464\n"
      ]
     }
    ],
@@ -680,18 +693,18 @@
     "        pval.gaussian(0, 10)\n",
     "    else:\n",
     "        pval.set_value(0)\n",
-    "    print pname, pval.shape, pval.l1()\n",
+    "    print(pname, pval.shape, pval.l1())\n",
     "for b in range(10):\n",
-    "    print \"\\n\\nEpoch %d\" % b\n",
+    "    print(\"\\n\\nEpoch %d\" % b)\n",
     "    x = train_x[idx[b * batch_size: (b + 1) * batch_size]]\n",
     "    y = train_y[idx[b * batch_size: (b + 1) * batch_size]]\n",
     "    tx.copy_from_numpy(x)\n",
     "    ty.copy_from_numpy(y)\n",
     "    grads, (l, a) = net.train(tx, ty)\n",
-    "    print '\\n loss = %f, params' % l\n",
+    "    print('\\n loss = %f, params' % l)\n",
     "    for (s, p, g) in zip(net.param_names(), net.param_values(), grads):\n",
     "        opt.apply_with_lr(epoch, 0.01, g, p, str(s), b)\n",
-    "        print s, p.l1()\n"
+    "        print(s, p.l1())"
    ]
   },
   {
@@ -707,7 +720,7 @@
     "       and visualize each (height, width) thing in a grid of size approx. sqrt(n) by sqrt(n)\"\"\"\n",
     "    \n",
     "    # normalize data for display\n",
-    "    data = (data - data.min()) / (data.max() - data.min())\n",
+    "    data = old_div((data - data.min()), (data.max() - data.min()))\n",
     "    \n",
     "    # force the number of filters to be square\n",
     "    n = int(np.ceil(np.sqrt(data.shape[0])))\n",
@@ -726,21 +739,13 @@
   {
    "cell_type": "code",
    "execution_count": 15,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "NOTE: If your model was saved using pickle, then set use_pickle=True for loading it\n",
-      "conv2_bias\n",
-      "conv2_weight\n",
-      "dense_weight\n",
-      "conv1_bias\n",
-      "dense_bias\n",
-      "conv1_weight\n"
+      "NOTE: If your model was saved using pickle, then set use_pickle=True for loading it\n"
      ]
     }
    ],
@@ -752,24 +757,19 @@
     "x = train_x[idx[b * batch_size: (b + 1) * batch_size]]    \n",
     "tx.copy_from_numpy(x)\n",
     "\n",
-    "r = net.forward(False, tx, ['relu1', 'relu2'])\n",
-    "\n",
-    "\n",
-    "    "
+    "r = net.forward(False, tx, ['relu1', 'relu2'])    "
    ]
   },
   {
    "cell_type": "code",
    "execution_count": 16,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJztnWl0HNd1529VNYDGDhA7AYLgAoCLuEiUKFp2bEsek44k\nJ854mTO2Mx88drxEmjnOzJmcyWTiLJOTyXHG8thJTjKyYseWJpHO+EgxJdlwrMV2xEUkRYmSuIIL\nSCxcQOxAo4Guqvlwq957QDcagFBV3dT7/770w6vXXRfV9freeu8uhuu6BADQDzPXAgAAcgMmPwCa\ngskPgKZg8gOgKZj8AGgKJj8AmoLJD4CmYPIDoCmY/ABoSizKk33Y+lReuBN29R0nIqJ9q3fmWBKm\nq/910c43mSBPZuZ8Zy27ciiJpKv3GBERmY3njKWMh+YHQFMw+QHQFEx+ADQFkx8ATcHkB0BTMPkB\n0JRIt/oyEmQyEWNJOxzZPyImL4mbSq3484IgtnYNERGd/UoLERGlym1xzJjl32/DkePdAr6m8QGL\niIjW/OmBUOQyd2wW7WRDKTcc+X0aXtMuYhljCSm39fM3vPGyL5fEWppFO9Xbt+LPsyoriIjIbW4g\nIiJzaloccy1P5xYo029mloiI7O6L6R9mWiuWJxPQ/ABoCiY/AJqSc7PfN7fGdreIvviNGSIicmPS\njDen2TycqSokIiKnUB4r/qdXA5PHrKoUbbeFTTbn9ZPcoTxWGLECHl9aLPqm79xIREQFPzsWmDxE\nRJTi/720l8/f9OgJcciZnk4f78l58U/3EBFRrK1VftSly4GJ5bxxSrQLsozLdJOZt23iz3jrdGDy\nqJz9691ERFR/SJrMZb3p91XBT48SEVHvJ9aKvsZvrtzsp5oqIiLq27uKiIjWPNUjDhkxTyZbPqvZ\n1fzY1PNH9xAR0dqvhfOopgLND4Cm5Fzzp/r6iYior
 GtE9LnJJL/a6YtBRd6rVVsr+oJcMrIHb8o/\nhkbmHlQWJ91Z1iL2yIzos5IOhYF/jRr+6hoRETmLLZJ5chobJvn9AWr7wOi+FOrHb/69M0REZI+M\nLmn82G3ye2wM4Pz2Bb7mzY8OEhFRanxcHsy0gHeJX2IfvjuAsy8NaH4ANAWTHwBNybnZ7+NMTaV3\nZvEBsG/cEG0zHufP8B4XghNqrnltlpTIQ768igln/vJ4sOdfRB4iIud9HOI60i4XHgfv5nG1Pwln\nfzgbZnm5aBsN/GiWquM9b+PgG+JYxoXKAFmquR9r5EXd+l9kW7J85ziT6fdJrLmJiIjsq9flwB0d\nRETU+jT3ReH9AM0PgKbkjebPyO5tommX8i+za/I2TewFuZ2WbbsrSJztG0XbOj/ApymUGsNfmIuS\nyRa2emJJaSWVdfPXOtrOfdZn94hjlY8fClUeR13Y8tpGN/9p7twiDrkWfz/usbdDlUcldR8n3SgY\nl4t7zizr2Jofd0vZSnnbzZmcDEWO4ffytraVlF6F01Wsh2vezPAG3+IL2NMPmh8ATclrzW+eOCfb\nJv9OmdXsPJG89w5xrKhniIiIUhcuhSvQYfmzbPvbaQWFos+qYYcOqq+R407J/yEMyp86wg1lPaDC\n0xCmZ5Wc+V87xLHKx0MVJyvCWUrBaqgXbfva9bTjQVJ45CwRzYvfWMPP/Ooa0rWH2dGm4dvhONpU\n/oidtNxZGTtS7jmXOW280Xj1q/eIY42PhBSbEcqnAgDyHkx+ADQlr83+TFt3TiJBRESWurjmbdeE\nToatR9/Tj4jIvsmPH9TekjYuNDJ5+3l9jhcPEW8IZ+EqCNypRGTnmrMY6TM8nNY1upXN8bDuKmc6\n/b4W9473morA0w+aHwBNyWvNv1Sc8Ylci0BE0sHFOZxpvyZ6jF1biYgo1V2+yMhoUBdHfYspozbO\nMeVnczctfAegyvPhxImoQPMD
 oCmY/ABoyq1n9mdYdDMsz/NJ9YBywzebiObuGZte3rZcm7J+gpST\nX2F//84vHhHHclkvzSyOi7atLJTmA5f/UO6rr/s2JxiJMrugVVFGREQje/i7K38yXE9MImh+ALQl\nvzV/lqg+a+M60XaueNt+IWv7TAtWaobfILK+Lhc/s+/JP5AbU+Y4f61b/rCX5cpRFmL3PexZaE15\niU+UtF/5wvWHWOO3Pi+tNbHtFhJWNXvz2cqWsDvB16jqEN9Dc74xZO8FAARJXmt+4StPRKMf4njn\n+CDnNzd+KbfT3NRstIIRUax5NRHlJpJPxY8J3/SwTD/m5xrIddUBP34/mtWXxbE/yPEgw51Foq/p\np5wazT57PnJ5ZiqlJVnS5zn3XGFrLSxtrwLND4CmYPIDoCmGG2S5rEVwrrbncqcJAC0wG88tKZMN\nND8AmhLpgt/92+6L8nQL8vybLxIR0b7VO3MsCdPV/7po72u+PYeSSLr6OBnpvpZdOZaE6erltG35\ndn2I8vM+WgrQ/ABoCiY/AJqCyQ+ApmDyA6ApmPwAaAomPwCagskPgKbkPLAniPBJv1CnUVqyyMjF\nsaqrRdvu5HBZOnRixZ+7EoxCDgAZ+DLvubd//Kw4trWCy4YNz8r/Pel45bpmOZnH+cc6xbFV3115\nkgijgD8/sVcWAxnq9G4lxbfM8LJhOF5FM0fGsdCaLi+E9mh6IY9lk8lL1S9csqVddKVq+HoUXFXC\nd890UxoBlnqzKrwipauq0j9/NkPolVdoxR0dkzKGFGIMzQ+ApuRc8/tpsNSkGJf/gBMslPYrxScH\n+LhfqDO+/1VxLPEhLuhZcmjlYZm2msf9UHpO91zgevULCsb5ehx7e704NvUIaxRjVGoz/1om7uRx\nL33nEXHs4999T2DyqN/B6v3L+4yB/8TfcdPRFYtDsbZW0b74F6xpYzE2O1JHpCVXcpWvX3K3LGc+\ntYMzGzf
 sl2G+5U8dXrlQvnZv5iQrU62V4lB8gLNNm+OyZoHrF3yNscUyuUUWhY0/K69zkEDzA6Ap\nOdf8ftJL9Tlr/eOcIEN97pmPmlxxaBP/apaEn/MwK1YtF+i0B28uMnKZeNem5rGDRERU9w/y+d5O\nLFzxJpZgjfj1mwH75/uJJjJVC8qWhEIZX/NWcAk8Uz1XRLvtc16NAm9dwh46nfW9yfvvJCKiG9ul\nHgykyoG3DmGfuUBEREXd8ro4fs2CDG+zvIKdVnP4tRag+QHQFEx+ADQl52a/QNmu8c39pW5xFI5G\nkyMktr5N/uHJ61ry99PuvhiuAJ757yimvuU9Nl3+0lbRl6hng/K3PvwCERF1ffX94lgBvRacPBlM\nfKusVLTH9m4mIiK7kOWOJeT3VPL04QU/YyXY82smLJKsZriDHxnrXg8pD6T3qONmeESy6urSxs1s\nbyMiouLuQXEorFyM0PwAaEr+aP5FMO7i7Txz0itvfENuw9V8hxfC3HK5SGL4WycBkrpwKfDPXCnu\nDGusxFZpDRSX8oJSSyFbTi1/ck4cuz7CFoJ77O1Q5LHH5CJt2X5OLuFvDSY+tlsc87dz1z96QfSl\nrt0IXJ7k/XeJ9vRDfM+sr5QLsmdPsF5tfOQIpRGgs0+mz7XXNYoup5inopHyLMqYtIh8JzZnejpQ\nMaD5AdAUTH4ANCWvzX5/35yIyBicu+ef2tAk/7jB5uL0PdKHvfjoBdIBv0BH++cVH3mbF48eL+Tr\n0fvQbeJQ8R/xtap+MHzZfHNfnPsZ6anW+gy/Dv6m9DiseiJ4s7/45/K6lBxh/4iRVfK+qtvD5vXZ\nv5GPJFv+51Uimus/EAbGGzJGI+YVmzVXsUeis0rZ5+/0StMFXO4Mmh8ATclrzT9n+29s7haOpfzt\nb6IMbpNhY2sC8Bl/p/iRXERzF8BCwVs8cmfSPeZcb0uw+ozcLDL/VcilzZa6decVVS3r
 C7dUt28Z\nERGR3x6U22jVXpkua+Zu0Tf4fi6TXfWDkDS/v02sWEb+ne7LayXlNuBsJ8sTtKaG5gdAUzD5AdCU\n/Db7s5DJ+69gMrfVwGJNvG+bGriaUzl8zBJe4Or9DeldVvkMVxeup57o5YnLsFljLZuysXPXRF9O\nqgp7JvhYm9SDDUeSC42ODGdtg2gXXPM8XgM+BzQ/AJpyy2n+TBp/7NN7iIio8YXrUYsjQjCJMi+6\n5QI/7Vf/5znNVn29vC7Vf89pvzKFk4Ymjxde6/pbVkRkxz2PtlPS+zCKmvQsiLQQzR0cf2AoRmP8\nOMdoBK1pl4IIC49Jvexc7gvlXND8AGhKXmv+bFF9yQekz3bRsPcbfTPctFuqlnc2cnJP++hboZ5z\nMXwtf/G/3yH6HvxVjpjrPsPbRi2/Lbf3UurWVxjyFMhbauJBLmA52cgavalrQBxzPe0aurZXtLyf\nMo5u3yz6zn+8jIiI1j85KvrsoWjSt1k1q+Qftdy2KznFWOySshaSDGcNApofAE3B5AdAU/La7Fd9\n+2e2rSUioptbOLyx7vikOBY7E64Pto89Ik1DOjq68MAI8b3E1v+ZrC1w8h87iIio4wbnQkxdD95n\nfjF5iIhKf8iPH356jzkLaBEt7qkJM3o+zzn87bg8vvEx3pYNPRGLgv/4YVRKT1AnziHo1tnLRESU\nGgn//oLmB0BTDHeRNEdB4lxtz60XDgAaYDaeW1IWEmh+ADQFkx8ATYl0we+Be34tytMtyHMHfkRE\nRPtW78yxJExX/+uinW8y5Zs8D9x1f44lYZ478rxo72u+PYeSSLr6ji9rPDQ/AJqCyQ+ApmDyA6Ap\nmPwAaAomPwCagskPgKbk3Lff9cpqjW2vFX12ATsolV2R5YkKhjkTbbKBQzCHNsmUUDWneFzRRZmV\n9d2EH0o8+LEtREQ0dJt0lLSrOPmVUSDTc7gp/k0v6uNru+F7MpQ
 2iJJjfsHSs1+UtRNcT40UDUnn\nMstz85/1XNhNJTK15c8OrFgOgSP/99n1jZ48LIfhKIk7pjm02ZiVUQauly/fuh5sGK9ZxPfn5Ee2\n82u9jGUovcbnLx6QJdZS5RyaPdzOrzVvyWPmK28EKpv43FA+FQCQ9+Re83spikq9/OkL4f9Wx7z6\nkvUvymPWlo4QJMsf/GKc5ixrsTX/LFNdFnYtXKDAL1J58dOrRd+a/3Fp5fKMc0Rl27PSMjN/ubiD\niVqoM0jclNTkxivsDJTJud2d96pi3ymrGlkDSysNnw2/qKZfpah4kfH+RKzjquo0/VF5reLpwwMB\nmh8ATcHkB0BTcm72m431/DqtlC6a9RZmyssWfJ/d2y/bJ7ngYaytNQwRl43IFUdEbmrl2ej9Ek6V\nTxxa1vum6liOiovB5uq1vcKo1rBcJFtKrHbvv5bXov2Z4OQxvEVjIiKrge8nw/T0mrmIfovxQlxK\nzcXYvHqBwcsRynvwyBQybywccevnZIzvf1XpXFKE7rKB5gdAU3Ku+QVqNRev7VSUiL4bu7l0cdEo\na7GqpMyRny8VcnyC0PZLJbaWswhPbJPbbiPt/LUmq1nrrPv62+JYkDZApv8zdd8u0R7uZC022sly\nND8Tfi4X1eoiIlGunIjIXsNWgV0kt90KzrEFOSeTbqACpWttyyvDffN+WVLe8YyXmh8cC0eODEDz\nA6ApmPwAaEr+mP0ZcE6cFu2aE3OPqQbn0OfeQ0REta/JjKfmyESYouUNTiXnxh3ukF/lrLdOmmzg\nq3T54W3i2Nq/5IUte2wsFHlcRZ00/D17pjW2tfA5y+Sj3cSnuMRa2VPLW8RctjzK46F75E0imqfx\nvOy+Tqt8bLKu3uTGYouF7xC/GE3VDw6mHfMfjEY/s0f01RxgD83UpcuBygHND4Cm5LXmjylbLu4U\n+zo7E+xd5s7KX/RVf8e/oM5uqeF0+VXzra
 OmEwuPuf7b94j2xL2biIio+J9eXWj4iih8WfqhO/6C\noLcVq5Lcztbawpu5wWAUFYp2rJHLXjuTsmSZv21pqHnya6pDlmpx1G3diQfZ2y8OzQ8ACIK81vyk\nFH00KsuJiMjyXlXEs9Crb8rOPHH4EZVpnFwUfGaspBLZlgp3u22p25xDv8JOXTXfCVMaIrLSKwOZ\nFeXp7Zgcl+rhClCxIJx9MrEUpx3FOajsaA8RzV3nCgJofgA0BZMfAE3Jb7M/C67iz53X5NDcjzVx\nYovkKmlm1r/MCU9yIZVxl1yQLTkVVqDqMvE8AN1SGXRrlqc/WkaFWcZLoM74uOhzp6cXGr6yc4Xy\nqQCAvOeW0/yuvwiYyWc6LP/sZWIUSWcWtWR1VFgVnDer/zfWExFR+WXp0R9lKWofP/7g1GdLRV/7\nfwwwjddyUdJ+pdp4+48Oyb3SWEszNyIsYuun/XI7uRQ9KVGG9lg4DmvQ/ABoCiY/AJqS12a/q+zz\nT3XUEBFR4YiX6OOV19PGZ0v+EQV+OGmUpr6f2ffKF7aKvsk2XsSqP8Dmbfk/hus/rxJbt1a0T/4u\nm9TFV/i65MTUV0z86S1szltTcsfcOMgeiXP29EM2930TP/EhuQBqF7IeLnn6cPob3GCTsQg5QvlU\nAEDek9ean0bkdkfRcxfmHjOlR1astTkqibISZRIPH9vzSV/99RwuoCk4126IdseXenIoCeOnhCMi\nir2QnigjNC++LPiZfYueO7LwoJBSd6lA8wOgKZj8AGiK4Ua4l+lcbY/uZABoitl4bknPDND8AGhK\npAt++1bvjPJ0C9LVz9uED+x+IMeSMM+9+pxo72u+PYeSSLr6uPxWvn1nH1kbTsmv5fKTHpkMJd++\ns6UCzQ+ApmDyA6ApmPwAaAomPwCagskPgKZg8gOgKTn37fdLKp/76gbR13Q7F94sK5TRcVWFnLe/\nuXiEiIiuJGRu9ZGHu
 NqKe1wWpHyn2DcGRfudRueZ2zfJ9tB4lpFLwy/b7MtjlsgCpqZX9NEtkWmx\njASPS13pzfBhwfmM+0lDiIiMao4unN5YL/oStZxqrWiEYx6Kj8lEIvbgzcDkUFHrORARmaUygYi4\nVlNK3n6veo6KUVCY1rdczGJOC+Zu4YQqyRr5/Uw28XVJVsrvomCC/d9qX+NKSnPuZZToBgAECSY/\nAJqSc7PfvnadiIiaDraJvt4SNh07H5PFJEf6OTRzaIxNsmufl6b1f33yCSIieqxj3YrlMdWEIBtZ\npr69nEikrE8mVfBNWScmTbLiF7loyFSrNIfLAjD7TS9kue9BzsZb1S1Dh0uuePndlBiN6dYqIiIa\n/CQXLmn6RrDhvn4Y7Kn/IgujFI6wHmn+hXxUKrvCj2oz1fyd9f2mrEdfd5zDWq2XX1uxPKZXCJSI\n6PTv8/9uWHw9is7IrLzF17kvUSu/M+MODolu/ZrMZ+yemRc+/k5kauACoDN/zp9/5arMNl1+kK9H\n6TUl0UgVy2R+Y5iIiMa/dbc4VvJMOKXVoPkB0JSca34ftXBk54ucN13NXT6fyksyScP/HfDLGV9b\nsRxGXMknP8ELQ83PeqnDEtkXAFNekoahzfKylqVnG1s2fsbd5u/yIpk9Ki2iTAmefB1T0sjaw0/1\nNf+975RUXz8REXX+nixu6S9GZkpo4ucyLiuVZaftItY76cW0lo9zSS5sbvrP3j3jpb5yRrNbXqOf\nuIOIiG7uktbAqjMrl8kvIRf7GFuS7TQi5Z1Iz8brVwroqeYCptZ6eawkbXQwQPMDoCmY/ABoSt6Y\n/Sq+ua/ul/d8lAtyJJo9s1L52Ur+DS/0VQRg9s/BZtNR7Jv39mUd7ryPw18bjoZTXimTye7v+TuT\nk2l9JVf5ccVWa88HuGesnjMbpvcoNdYmv7TW73Ml3KCzHjrq/zqP+T4ARESu99xR0RNOxuVMJr7l\n
 +xtMy3PaOzYSEVGqjBcl1/w/+V2HlQEHmh8ATclLze/jnDgt2omvcBKHgirWqmff/31x7GOb9xER\n0cyPlYWtLBogCJL338XyTErdVTDgeWcNXBd9bhNvWxpT4VgDE3tvIyKiRK38HZ8tZe2++kX2Xgsn\n63tm7HvvEO3zn+Tby6pijVuoOK25ZWEtY81leu8O0b78Kd7Oq6mR2njyEF+3ysfllqOvaYPw9MvE\n8N4OIiJq+JL0eNxdzbUV/vkaW7vGk3KLUqTaC9jTD5ofAE3Ja82v0vkQ/zL7W0n7SKaXOvftNj72\nDemo0fG5o4HLIAo4ElHsNOend+NSO8w0s+VhnT0v+pLv41/y0jf7A5eHiKjsZyf5VclPb3oFS5Pt\n7BSU+JTcYit7yqveE5K/eMHBk6K96TDrFrOaHW+mO5vEscuf4Paabw6IPieEUtQlB7pFe/NrvOno\n1FWJPvse1qpn/1qmB9v0O1y007XDsZmqnub935kfy4Ku/1K7hYiIEndzlaPCR+T2Zeyz/D2mrga7\npgXND4CmYPIDoCm3jNmfrRRWwwE2Ycc/mYhKHKIZz+tvRprbRWO89aVKOr6GL3Hpm+GIkWkryeln\nU9ryXu3PSD9xw68DP5O+7RWIPBlMd8cLoY31yUef+Dr2ZDPWrZEDT50LXp4JZTvSbw/KMN76U/xq\n/rtdom/6A7yIWvTiicDlISJy/FBxNWTc28atPH+JiIgubJePak27+XG2+Ecw+wEAAXDLaP75xNa3\nifZ4K/+GGYcqFxgdDb4TkOUtuBERVVyOvninj1nGfuXFg0rEmq9tIigEmY2pJj6/MbLyqMeVYFh8\n79hF8noUDkdXYn0+vgNQqkreN6UX+RoFvfwIzQ+ApmDyA6Apt5zZb9VyYo3ej8q66pOdvHi1+Xfk\ngpFN0eBkyEXX/2kZk9D8XDj7+9kQOf86ONlGvFea1lF6+80ndZ9cVKu8wJKkr
 t3IlThMRxsREVmz\n0oPeOs+Pb1FeK9NbiL3x65zwpPiy8ljWfTmcc4byqQCAvCevNb9VVyfap/6EI/fKGnhra+Zt+Uu9\n6Vu8lRS2P/9imX1v/nvevmr6xbDsVLYCw8DXGOpWqLmeNf5UA/vPFz1/RL4hwoU+q5Mj1RLreBFr\ncJtMZdXyV+zl5jgh22im/H/dWb5GsQZ5X116gBdnW/fL7T9nLH37NFCRvKjLxAe3iL7JBp6Kw1v4\nvu7831fEsVQinC1saH4ANCWvNb99Qz4PdnzJ86V/L/v0F/TLZ+nUxZ5I5LHqakV79G5OGjlbIn8/\n6w/y878xtrQ49yAwvRRdI7/SJvoqT3LKKKHxo9T2yjbnyO18veKDbP00f+uYOOa8w5oIy5anXmr5\nc19mhyJT2X3d8D2+j+wr0a3N+GsyqiVkej5XHX/OsQipwcG09wUNND8AmoLJD4CmGK4bVpKgdJyr\n7dGdDABNMRvPLek5D5ofAE2JdMHvA1/8rShPtyA//9v/Q0RE+1bvXGRkNHT1y+T++SZTvsnzwS98\nIceSMC8/+qho37/13hxKInn+7ZeWNR6aHwBNweQHQFMw+QHQFEx+ADQFkx8ATcHkB0BTMPkB0JTc\nB/Z4Pn8lP5OZUpdbvCG2bi0REU3c1hCYWHmFydUkzW1c5ml4m8xV6JfpcgqU4V7gSnyQL27ty0p4\n6BVZDCJszNJSIlLCjW0Zvmu1cmBU6sKlFZ8nUSNv4+vv887lsJNb5Ul5LH6T03OoBUOdHZzopOSl\nMtEXRN5Fo4TLbaUGvIy7KwhdtqqrVyxPJqD5AdCUnGv+4gEOf82k7c2dMtmB64WlWiOcaEEN4xXt\nd6vm97SGXcaJOwxFiTQ/wanLnGGZQMTXtFYDFwk99d/WiWPt/yEczT/+bzjPfPUB+fmul6/fMDl5\nhRqiPbybS1CVB6D5a/9Flvyq+v7in5cpx7NfeJWIiAKI
 gM6m8Y0YT7tstSiiAJofAE3JueZPrObn\nQqtaJne04/yMm/EXuIXHxyNK4JFPGK+wf3vlUVng0c6SFMO+xqXCzeSGcAUjovInuQDoUnVZsoK/\n3PIAzj25WSbsKGxkve56+fhnK7Lf4qVvXeWGkuos+cBdC4xeOlZlBcvhVUYyiuPyYJYCoLZiwYUN\nND8AmoLJD4Cm5Nzs97GLrbQ+w5G5P0peOcvjMmToTX1oV1rfuxk1c7BfeNPcsFb0OcW873d9N5ue\nHX8n88FFVc8gE+aOzaJdf4DN26Bz489UF875e7hd7oFO3sVZcO1Jedt3PMfboH49iKDx8/Wppr5R\nxd9L6pKSj39eUh1/+5qIyB0ZC0U2aH4ANCVvNH8m4l3HRdvOsi0Se4Gzwsb2bBd903XxhYa/q/Ct\ngOvvUTSX95M+vJOvmZmSWYfrenmByxkPv0CmsWsrnz/hlTMfUs7p5dM3quTGWxh1Fxq/eWBJ405/\nbaNo1x9i2eIj4dhJS8k2rY4xCth6MMtKA5UDmh8ATcHkB0BT8trsn7lP5o9zvT1/K8kLJ4XXpAlp\nn/IKdL76tnzzA3otAtY8djC9z0szN/Zv94i+qQ/yolt8/6uhy+Qe4+/DN57NuHwU8z06Jz9+t+gr\n/eHhwGVwPnC7aJtJliTWc130pQb4Maj9YXnu0c/I6xUGfsyDUSCnn5Pg65GpDJw761X0IJj9AIAA\nyGvNbxel/zY5hZ7nVrmMdIqf4leroixtPCCq+IdDon3jy1xMNBfLoZniNxI18jsOVq8xs2XKLe61\nkzVrlBHcjitRpdVPcztx79YQJFK2/xT84p3kvaqefv52btBA8wOgKZj8AGhKXpv92TDs9Mpf9qa1\nGUZqjJcEZOITMlCl/ggvlOZL3bTKCzOLDwqRiUaeAkXKQpu1vi1H0hAZ/l6+YvZbTRyq7o4G65sB\nzQ+Aptx6mt9TWUVKCKZffz5ZE87
 CyC2Hp/GtavaeG9kof+PLnz6bE5HmM/FJ3uIr++HRyM89XS3j\nSEpupnvxJdeuilIcIiIy4nzvZkqz5k4mQjknND8AmpLfml95MI0/u7BTSvIjd/JwM4D8S7cantUz\ns1c6NSVq+Wud8RJmrH30nDhmz+buGXv6wd2iXflSNxER2StIbLmkc1ZJLX/dO33dUXmfFD/D95W1\nuV30JUvSI0yDRGh5z8EoE7GWZtF2J6dCkQOaHwBNweQHQFPy2uwvHJ0V7VhbKxERpep5EStZK33U\nXEtDc9/HSwJR2CUXzkq8RBDuTd4ussfCSQaxGL4Pu1nLC2glL8nYC3tyMhIZqk7K7bHKJ95OO+6H\nHU81lkQwjbyaAAADhUlEQVQiDxGRPZSep8/34rNWsedqWKa+CjQ/AJpiuG507h7O1fZ88S0B4F2L\n2XhuSaYwND8AmoLJD4CmRLrg95G1uxcfFAE/6eG93X2rdy4yMhq6+l/PtQhAQ6D5AdAUTH4ANAWT\nHwBNweQHQFMw+QHQFEx+ADQl9779Xhhupnzly8UvaxQUVgUXVJze08Gv1fJy+eGydoF0prJm2YGx\n7qD03XbeOh2oTAAEBTQ/AJqSc83vJyccuatJ9MWHuMDkZKMsr1w0ypV6klX8ezW6Xv5utf7x0oox\nLhc/7qHnV/kybXxSRlrFBjztPiMjD/1IrML9xaIv8YFQRANgxUDzA6ApmPwAaErOzX67j/OYVao5\nyW3O61aQSC/v5BvUFXduDls0UcO+4/ff5L+VBBSpLO87P9Qi2qvpWiiyAbBSoPkB0JSca34fZyJ7\nWid3XtZZ4+Aboh3z0lbZvQPBC0ZzNb44p1fVxR2VKbJu/FonEREVPRuKGAAECjQ/AJqCyQ+ApuSN\n2Z8J++4tom142f/8eutqttrUxZ609wbt7Tefgb3sl+Baq0Xf6BZeqCzulUUfrGrOxqrWWwcgH4Dm\nB0BT8lrzF5
 y4oPzBohZUsr/9+K8rKcE893q/9FIUNHzvOBEROdNyO7Lee7U2rhN9p/+Y4wLaHz4c\nmWwALAVofgA0Ja81v6M6+fhViscmiIio5Eq/OOTu2hShVIyq8edjd18U7aLGsijEAWDZQPMDoCmY\n/ABoSl6b/dkwCqTo7mH2vTfjSvFO24lcJh+rqlL+8VZ5zuQAIBvQ/ABoyq2n+b20X85Uegljo1A6\n9rgZIgKjovt3pXPSxr/gNF52roQBYAGg+QHQFEx+ADQlv81+U2bGnZ/d1ywtle3aVUREZPdHlzjD\nqq0hIqKJ924QfSMb+HK27ZchwPbNochkAmA5QPMDoCl5rflNZcvs+kdZw1peTo/an0q//yg1vjjn\n4E0iIioaahV9LadZy9tnuiOXB4DlAs0PgKZg8gOgKYZfmCIKnKvt0Z0MAE0xG88Zi4+C5gdAWyLV\n/ACA/AGaHwBNweQHQFMw+QHQFEx+ADQFkx8ATcHkB0BTMPkB0BRMfgA0BZMfAE3B5AdAUzD5AdAU\nTH4ANAWTHwBNweQHQFMw+QHQFEx+ADQFkx8ATcHkB0BTMPkB0BRMfgA0BZMfAE3B5AdAUzD5AdCU\n/w99eh37iWlJHwAAAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD8CAYAAABXXhlaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAGwdJREFUeJztnWmQHVd1x//9+s2iWTUzkmaTrNEyY1mWsGxLsmWMWYwt\nkJMQCGBMOSGh4gAJFBRZigpVBAJZWSoVioQlwQbsShnKEOLYsRxcIGNsIdmSbGNZ0mCto9FoZrTM\nvr3XnQ+nu2+PXs+MHL++3TP3//vy7tzbT33U3eed0/fec47lui4IIWaRSVoAQoh+qPiEGAgVnxAD\noeITYiBUfEIMhIpPiIFQ8QkxECo+IQZCxSfEQLI6T3Zb5j2p2Ca4s/sAAGB7y6aEJRF8eYD0yUR5\noknzPcs0dVpzHUuLT4iBUPEJMRAqPiEGQsUnxECo+IQYCBWfEAPRupw338m2XRG0c8dPJiiJYujO\nGwEAW//i2aAv59gAgMc6rwIArP3iVDDm7n8pVnnspUuD9uiWNu+k8lHeM6pNjjTj3CzLfyXnQ9fj\neJeMjY5GfqfY0OITYiBUfEIMJNWufra1JWjnTncDAEZ+5wYAQNXR4WBMl9s4vka5sVnP1bcb6oM+\nZ3WryLP3RS3yAMDAavntfvJbW4K+pV9/BgBQ9bEKAMDZm9TxjS/KLXdzuVjkcS5cCNplj/ZNG7Ob\nm9Rxm9bL54GDscgRhbV5AwCgd0t10Lfs2/sAACM71O67yv/eDwBwpyZjkaPrLXJf2v5zPOgbvVVk\n67lRXtPaPv1MLOf2ocUnxEBSbfFz3WcK+iof+iUAwF7dpo7TJE92qNAC5M+dD9qTm1cDAEo1yQMA\nox0TAICm+wvHxhplVm3xYdXnOvGGS1hZ9UjZjcsAKG8td6YnGMsuKgcAOLFKM53Tb64BACz/6r6g\nz5mQ6zdZrWxgTat4JnFN4E7Wyf/aeeFQ0Ff+gnxO3
 XZDLOe8FFp8QgyEik+IgaTa1Z+69bqgXfKT\n56aN5Y4e1ywN4CxSlyvqF7O8Z0SO0yQPAKz8gUiSfWJv0Oe7287qMQBA7SMh997JxyqPM64mrKyR\nkemDGVu1p3S9oCnGlsl1CMvoM7xcRbLWdXXHK0jU25Z/beYMqC0OtPiEGEiqLX75/mNBO295P4UJ\nlvzK7Npf0JddsTxoO50ndIoDACh7dG9B38U7NwMA7KxYXOsZfcuLYfIXB0QOb5LPHQotwQ4M6hEi\n5GVc+RV5nqJ8jYkG5afFtdTps+4fC+VwbtoIACg/a0d8o/jQ4hNiIKm2+OGlMh+rrAwA4HrLMEkz\ntaIhaFunuhKURHH29WK9Gn9cmbAkQr5XNvJYpWqh0xnXdP9Ccxrh5UQff0NY4259nmSu52xB34k7\nFgEA1nzheQDxzxPR4hNiIFR8Qgwk1a5+FGlx8f0ls+yZi0Gf/gUqRWbDuqBd3TIEAKj7kUw26lxe\nnIY3sZbxdulZFRXBUL6vL/Iruum+RSaNO/5UhTXrcvr9SU8AyFV4S42XLoHGBC0+IQYybyx+ptzb\n2x2x+SIJnBskmsr9xYE5jtTDiXeqKEH7Kfl0Rl9OSBpPjpoqAGpZL5PgUmyYbFNj0K7tFNsX9xJe\nFKffvzZot//H8CxHFh9afEIMhIpPiIHMG1c/LS6+T/a8TMLEu/N9buzFtQCA7PUqAcaKj4vbmORk\nIwC4eZlWzHoJOKLW0ZOg8+Org/aaz0mIrs4JUH8vykhr6Ky7X9AoAS0+IUaSbotvhUKVUjAxZK/v\nUH90pcN6nf8NyaRbXnIu6HMvDCQlTuCBAAA8y5aGexfGDT1WSXiSY7dfAwAoHUjO7tLiE2Igqbb4\n9jq13DGwUfbEV/9I3sniSoQ4G+4plQrMsjQFTs9B7f27pRFKvZXkvIO/dJdGBu6WGgStu5Kd/VjU\nLfNDy5yKOY6MD1p8QgyEik+I
 gViuxokXp6c9XbM8hCxAMk2dc76H0uITYiBaJ/e2t16r83QzsvO0\npNDa3rJpjiP1sLNb7fdPm0w7rn5zwpIIj770UwDpe4aA9N2zy4EWnxADoeITYiBUfEIMhIpPiIFQ\n8QkxECo+IQZCxSfEQFIdpPOqwzljDpwJl8vKpaR4hl0jNd+rHi0J+m6qewUA8PCZ1wEAhu5vDcbq\n7nsmVnmsOhWWe+yuFgDA5GK5j5kpdVzTHgklqtrVGas8mUWLgnb+Wgmrzl4cU30vHS78UgIBWPYS\nCUJz2poBAJnBkIxHXin6+WjxCTGQdFv8EKPvklJHgyskV3vrY73B2PnNSwAAix8M5UbPFz841Ulj\nyGmpWPpPtjwedH3sCx8FAAyukb8P/+2/BmM7fngLACA/GE/RSuesype/6tuS5CIq5dbYO7YCAKzy\nsqDPjaGs1vgb1gft5s+I5cy5yt5tWSw1CO59cHvQt+LzT0sjbg8ylO03KKvVLwlVej68LRhbSotP\nCCkG88biX1wjln75VyURRz6UMmnyzUsBAPbSJUFfVGHC18zU1KzDVokUhdSZJGTwTZKspDbzcNBX\nf98eAMDSNSul4w/U8Vb9Yu+L8Vj8TCj1lrNE2plBsarh3PUVXZKMwp3jmr5W+jeqQp3Hn28HAKz7\npEps+f333w4AyN2u8trbdXUAgPxFVSUpDnp3qKSf9d+e/rwuOqcScWa8CkTO6GjRzk2LT4iBUPEJ\nMZB54+rnvTmgqKyok4tlEibf1x+rDJEZWUMTQFaJXE6drn71r8WN3vHYJ4K+Dkdc/d43yeTRY6Nq\nAi13/GSs8uROd6s/vLbdIOW9rDpVJBKj3jWaDLn6tl10eYbXqteL7ID8++H7ONLiPTtnVP47Z2io\n6HJEUX1y5udkqlLZ5GK6+D60+IQYSKotvl9xBABW3XscQHR1GD9PehxLeHORXbUyaOeOHtd+fufA\nQQDAuj+
 vDvosb4JtyV1i3T/y87uDsQ48p1E6T55a2WQ02aQm/uy9UtAzUxFvptn1nyv0cPKh52ps\ntVjduj1qA5Su56j0579S57xkrGww3to+tPiEGAgVnxADSbWr706qyY9c95lpY/1/pHY2NRxMrkCC\nOzSS2LnDhCek3G1Sounf1n4NAPD7f/+JyO/Egb8GHkXpK2oHX27C26UXs6sftZ9j+N1bg/a1a48C\nAAbuvyJWOaJwJwp3KlrXXw0AqDqidonG4fTT4hNiIKm2+NO4JFJvpFUtoy29V7KL6kzaby+V3YL5\nvr45jtRDeCK0865yAMA9ne8DAJQ8/mzkd2KXqdLbcVYl8qBbWXw/qlAr3jN05g2qq3+X7Hxc9eRe\ndZhWoaYztLoKAFD1g1/Geh5afEIMhIpPiIHMH1ffw71JJq5qjimHzM3FG+gRhVVaMvdBGvETOQDA\nv+y4DwDwmc9/EABQh3QkDQnvmLNDCTJ0YW3ZCABo6VCvZ9Y35JUtiT0gYTLl8jpU2V380OTI82k5\nCyEkVaTb4kek3jp1WyUAoO2LqlxQvHucFOEJtPzZ3lmO1IgXK3DqfW1B175Radd9b49+ebLqkXLq\nZTehdVKWYjOVlfrlCT1Dp94q8oweU97Guv95HoC+Z2gmBt4hZbiqH9yt5Xy0+IQYSLotfgRZb7+M\nMzY2+4ExEE4ykRaL7+91v/l9+4K+7x6SDSornRe1yxOe+5iqkffW0movjmBY/2an7HKVaNTaIpti\nWh+oCvqciE00SeBo1kRafEIMhIpPiIGk2tXPVKtQ0/53bwAANLysf+nOJy3ufRhnRNznE+9SOf9X\nV4v7msQCVTgRR8Zr+5EUs+3jj4t84+KgPdInr0XLhpJduouifo88W7oko8UnxEAs99VWq3kNOD3t\nSW6DJsQIMk2dcxYEoMUnxECo+IQYiNbJvTu23qHzdDPyyJ5HAADbWzYlLImws1vtQkyb
 TGmTZ8ct\n70xYEuHRJ38UtN+26oYEJVE8duzyQ3lp8QkxECo+IQZCxSfEQKj4hBgIFZ8QA6HiE2Igqd6r75y/\noNp+4cCMFD7MbOxQB3rJKDL9Khe5KdgdawAAL38qtA/eyypR+4LUhm/53svBUP6CuqZxMPYOlbO+\n63a5L9kBsS+LetWGstYHOkWemLMUWxMqtiPfJNcoMxIKxfWeHaeiNOjKXBiOVaaMl2F44nUql/9U\ntTzXuXK5VhU9qqZE9pmXii9D0f9FQkjqSbfFjyoP7Ej8kvP8ywVDmRUqQi0qbddCZGKFRJ/Z59Wt\nXPugROyd3C5W7JU/WxeMtX36mVjl6blBlbpu/5Pp5wpH58XteQTn6VUehXtKko7OGQG3dlV8AgFw\nvapH2SdUAdNLFTGzaX3Q9lO+FTNpCC0+IQZCxSfEQFLt6keRbW4CAOTO9BSMuePKFbLKSgvGFyJ9\n14gbWBGqKerulVx7DStkD/nZrer33SqR6+JOqcmjYuK2zZwL8dDn1YRs+0fjLRHlY5Wq58AvUpld\ntTLoyx07UfidYXnFdKviKejpu+zhMmJ+gdig9kCnkiuO0HlafEIMZN5ZfNj2jENpq26jg5oTMlVV\nOlBYKvxCu1yrylOqLy5L79P6wMz3oGSp/szI4fLhPq6t7J2fpXjaRHJFzFV+PAueHxxUcniVdPzl\nRWRCNnmq+OnmaPEJMRAqPiEGkmpXP1wMwfUmPdzZCmlYc6YaW3BUPlQ4Sebv5htdIa8BHfeqnWhx\n724oe/TZgr7h994ojblTwRWdbFOj+sN/TRxTk8D5iL0ibkaPnOGSbFatN9HnZXK2Qq8jziQn9wgh\nRSDVFj+M5U1+5LpOJyxJ+rlwvZR+tke9GIZONbsXe972iKWnM3fIhGL7B/YVjMVN5JLcxcHCPo3e\nYtjSz4gTr29Gi0+Igcwbi4/szMt42dYWjYKkE39ZCgD6rxXr1fK
 k2PfwspFO7KvaAQBWJh1xE1ZO\nrkeu/1zBWHhTjy5pw/fs0ipN/oae2M4d679OCEklVHxCDGTeuPq54ydnHjRwGe9SJrddFbSdEnFW\nqw7IRGjhnj49HLtTJhk7/lhiB5yE5PBxBwp38QVjmpbwpmEX2l1//34xQ3CjoMUnxEDSbfFnseR+\nlB4Rut+glojqXxSLn8TSZ3jCqnSTJNuI2i+vCyu0LOZGWFh/Uk/n9KOVFbVzx8YLxuKe1POhxSfE\nQKj4hBhIql39WV3VWcJzTcK++koAwORaFcNQtzO5abSB33xd0J7clwK7MqquSz5i/T7K/Y8bPzlI\nOO+gv+fBOTrLJHYRScGdIYToJtUWP7wjj3v0o8m/dBgAsPbuhAXxWPyzo0G7+sHeWY7UgzNSGH0X\nJL1IiKgMw+7Jbq0y0OITYiBUfEIMxIojg+dMOD3t6YjWIGQBk2maO+MJLT4hBqJ1cm97yyadp5uR\nnd0HAAA71t2SsCTCo4eeDNppu0aUJxpfHiCdMs0FLT4hBkLFJ8RAqPiEGAgVnxADoeITYiBUfEIM\nJNV79e31qqwyvibVYN64pBMA8OKQqrLT9TcS2VT2yN5Y5bncbLV+pBUA4PTZmKTxznXl2oI+a1KK\nLEaVgNaJX8XG9SLkksj2m6muDtqWXwwzlAAjCZmyK1cAACZWLw367BG5Z/YRic7LXxyIVQZafEIM\nhIpPiIGk2tW3BkeC9uFur/jhh8Rd67l1WTD24S/9GADww8eXB31x14HPrm6T84Sys+Z/fUw+q1XY\np13q1YufLH6NcwA4/Xa5DlWnVXGsqQr5PR++W16HVnz+6VjOHUV2hboHvbeJS2t5ok3WqGvV+Esv\nD9+eF2OVZ/z164L2ibdL8ha3SuUdLquWbLbN/65yFpbuLCz8WUxGrpZ8kSe3q2QyliPJOWrXyFjF\nd5TcUYVRXyu0+IQYSKot/ugGlYhja9uvAQ
 DnjkgSg+Yp9at98A/lOLtRTZbEnbhjeL1Y2spfdBaM\n5StLgrYdpAiLx+JPVcpn1Q8KrcLgX2+L5ZyzMd6uylLXnBCvK/vEcwCAzKb1wdjoiioAwKKsegTd\nXPErAAw3q39/yX75rL9f7Wm/cNcWAMDFtcobadolHpszXpgFtxgMrJLno/aw6lv2dbl/F353q3x2\nKHmqy4svDy0+IQZCxSfEQFLt6pc+ptbl9227CQCwEjJRde6m5mBs/ILk98h26clQCgDZMZmxinJP\nJ2vUZS2NuRRSrnLm3Cb2mP6yUJO16v9ednH6681Yc2XQLr0grwFxuPdhRpvUNajqcgvOmfPqf5QN\nqMzEcZevGl8in5WnQ/fOkedprFHkXdSnxuJ45aDFJ8RAUm3xw6z6u30AAPfaqwEA/ZvUL/nFp2XZ\naiXitfiZSmWxyl7wdlhFlYcKG1on3mxj7V+VJcSw3YzazaeLqsd/FbSdS0pE5SqUnak80CN9McvT\ndu8rQdv1LKcb2s033iA3q/pkSJKY09Gt+ueX5TQhzyLjLYOOLRPPo3FvvMvRtPiEGMi8sfj+e06u\nXpY2qjtUbvKGf6qI/E6xscLVeyLeAy3PG6n6VZ8WeQAgd6anoK/rDllqbHl6rGAsbpyRkYI+P+Zi\nslrZGXc83vdon1xPYazE2G9vDdqTi8W6V5xUe/bzBd8oLlF59Qfv2Djt77Kj6hmKwyuixSfEQKj4\nhBjIvHH1s8tlAq9ng+ypHjqpRF/20+LvZZ6LqHDO4TWyG63mJ126xZlWFspfosrs2q9djiiGrqwD\nADQ8q1zcKHdXFxfXqGen4XmZTMsfPKJdjvA9698kNnjpPnn1yJ2M9xmixSfEQOaNxXeW1AIAhq6T\nSb5lj5cmKU5AOBqt+pCXPCHmJbwozr/n2qBdezS5Mtlh7IZ6AMBkldiXzLmLwVgiEm6VCbTxBnV/\nWnZJghedFaV8prap2
 IV8mZy/br+U8s7HLA8tPiEGQsUnxEBS7epbJcqd77teXH0rI65+7QO7tcsT\ntYd7cLPK/Vf9M/0TRLBk59lIi9ou2PoPz+iXI4KxzasBADXHvT0YEXsOdHJ+gzf5eizUeeCQfkEy\nsh+k7xo1uVfzirj2+cNH9Yig5SyEkFSRaotvL1cReOffKNbW6iub6fDYcSMsvj0RmqbKx73nqxDn\n9dfIqZO7LNPJqN2No42ScKL++7J/P4kJPX8ZGAAG18hn28Nqd2Hc0YFR2FeKJzS4XkUvXvVlWd7M\nO3qeIVp8Qgwk1RY/nBe+/fekbXfIz7Z+2zodX47Kg2ovuP4FIQTv+M27443mulyyzSr1Vvl5uUtW\nqTdXE1Mqq9nIN9WpPzyXIzM2dWmXVqxhiaGoeVmlirNG9V4bWnxCDISKT4iBWDp3LDk97Yl4w4SY\nRKapc86ca7T4hBiI1sm97S2bdJ5uRnZ2S171tMkDpE+mtMnzpnvuSVgS4Wff+lbQTts1uhxo8Qkx\nECo+IQZCxSfEQKj4hBgIFZ8QA6HiE2IgVHxCDCTVQTrk8un96E1B2/V+zqtOS5BM7e5TwVjudLc2\nmbJNErAztaoJAGDlVUiMfUKCm/Jne2OVYahVPeLnr5PrYdeogKblSyQPYO+ulqBv2YHpxT4XIrT4\nhBgILf4CYVLVgUTbd49L3yoppXXwsyoZRcc9+ix+7w5JOFHZI8kuyvpV6OmJD0phzxVfUpl33ani\nhxYv3avqHyz55kszHtd68+KgPbFEwogzUws3tIQWnxADocVfIIyuVCmk/Pf4jPdp3XNdMGaVSY6u\nqDRixcZPAFp/n5Q4RyitlPUWmZOwG1UyilzX6aLLYPeqij3+FZrcvjnoW7THK6P9lNrnnr1dxp2S\nOYPc5i20+IQYCBWfEAOhqz/P8WsP1O+3Cwf9jLdDJUGXDhffJzvmNSIyx+a9NHxxuPdhopYvndKQ\n
 vbMLbZ9jL1wX34cWnxADocWf5/hLYEu+UVg9Z/DOLQCApqe0ihTQ+s0XAahMtnZNTTBma3I87Kuv\nDNq5WqlcM7BKPfblD58r/JIB5tCA/yIh5FKo+IQYCF39Bcy5jTJJ1f41VZhEZ8EoZ2ho2t9d92wI\n2o3P6vH1R9tqCvqWPTtS0Ge3r9YhTmqgxSfEQGjxFyDuNimkWTogFl9nRN5sTIaMb/aJ57Sf34/U\nW/LI3oKx0bUNusVJFFp8QgyEik+IgdDVX4CcubkSAHDFw/0Akq8sPPzeGwEAdYeSqE2rqOouvBLZ\n5RKyPGGYCTTsv0sIAWjxFwx2naoDP9osljV/8EhS4kzj3AaZZFz52T3azz1VoWxb7YE+ANM9oNGr\nmzVLlA5o8QkxEFr8BUL/b60L2s2/SPZd2ie7ug0AYOW9aLeIKL3YsVSkXb7zKADAvnJt0OdmF34k\nXhS0+IQYCBWfEAOhq79AqPuOCsu1F9cCSH4ZD468crQ9dF7+TECE6h/vD9p+zlxreDR0RB1MhBaf\nEAOxXFdf7nCnp33hJionJCVkmjrnnLGkxSfEQKj4hBiI1sm9t12xee6DNPDYyWcBANtbNiUsibCz\n+8DcBxFSRGjxCTEQKj4hBkLFJ8RAqPiEGAgVnxADoeITYiCp3qvv5l5dFngrq++/c+ED2wAAQyvV\nJqnMlHwu/+mwOnD3C9pkIuRyocUnxEBSbfGzzU1B250Sc3r8Q1IEsfqU2va/+LsSmRb2EOK2/n23\niDzN/6vOk5kSmZZ+5WTQd+6tFQAAZzQcEUZIstDiE2IgVHxCDCTVrn6u56z6wwsfXvnlfQCATIt6\nDfAdfKukNHR8vGkfOtp65JwP9apTerXqz3zkiqCvbHmJNI68Eqs8hLwaaPEJMZBUW/yJHSqar7xb\nJsec5w/J59HjSYgUcORwCwCgY6qrYCzvqN9TP7MrIWmCFp8QA6HiE2IgqXb1K
 /edCtrupEyc5SOK\nMmTbZDIt36WvDvxVf3VMzhnqy916PQDgxAn1e9rhHtcmEyGXCy0+IQaSaouf7+sv7MzYAAC7qlL1\nacwU7JPv6yvo6/+YTEAue2ixbnEIeVXQ4hNiIKm2+GEujdSz6mqDdr777KWHa8NuqA/aE5NyOZvu\n352UOIRcFrT4hBgIFZ8QA5k3rr5VVgYAcKc8lz8T+s2KeV/+bBz5y46gXb7PkymByUZCXg20+IQY\nSKot/rQJPa/tT6Y5Z5Kb0AOUB1LTfiHoW/Yp2dRDe0/SDi0+IQZCxSfEQFLt6vu79AAA3h59Z2Aw\nIWGmM/CuawEAYxMjQZ+fiIOQtEOLT4iBpNriZzaqpbJTb68DAFzxX7J/3zmSbIKL+qckAceivsZE\n5SDk/wMtPiEGQsUnxEAsV+MuM6ennUvchMRMpqnTmvMYHYIQQtKFVotPCEkHtPiEGAgVnxADoeIT\nYiBUfEIMhIpPiIFQ8QkxECo+IQZCxSfEQKj4hBgIFZ8QA6HiE2IgVHxCDISKT4iBUPEJMRAqPiEG\nQsUnxECo+IQYCBWfEAOh4hNiIFR8QgyEik+IgVDxCTEQKj4hBvJ//HxftMJ4RmkAAAAASUVORK5C\nYII=\n",
       "text/plain": [
-       "<matplotlib.figure.Figure at 0x7f0747eafc90>"
+       "<matplotlib.figure.Figure at 0x7fddc4be1e48>"
       ]
      },
      "metadata": {},
@@ -784,15 +784,13 @@
   {
    "cell_type": "code",
    "execution_count": 17,
-   "metadata": {
-    "collapsed": false
-   },
+   "metadata": {},
    "outputs": [
     {
      "data": {
-      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP8AAAD8CAYAAAC4nHJkAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADrhJREFUeJzt3WlsHsUdx/F9DseOYydxnMN2Qsj1OIFwJA0JSYqIKkET\naKsWWrWiqOIqVUpVRBFVD6RW6iFatUK8KUUF2qJCqFAPoSKIK1SUCkJIyAV1aOwcDrEdxzmcA9ux\n/Ty7fVnN/jc8m83uPM+T//fzbkbjnSH2j9GMdmdSnuc5APRJl3oAAEqD8ANKEX5AKcIPKEX4AaUI\nP6AU4QeUIvyAUoQfUCprs7O19XeL1wlTVfaG8OqeTeZ4WpZY6ztIW+8uUXfLvJVG2R0dszUcp617\nu6grt3+jchuP45R2TEHjSTd1psL8LDM/oBThB5Qi/IBShB9QyuqGnzs4GMtzhr+wQtSNf3mbWVGh\nnyr7P7FO11SLNnt/u8gor1nYKdrkavuN8lufyYk2+cPdUYaIIjJXyH/rk8sajfLEA8OiTWrz7sTG\nFISZH1CK8ANKEX5AKatr/qj2/2qVUa4/KN9hGF+ha/xi3KEhUZe7a4dR7g34uV5nvFHe9/gs0WbB\nw/Gs+VNZ+WeUrq83yoWBAdHGXbPU/JlNOyP13/3XxUa5fdULos01W+8wyvUbJok2dS9tidS/X+qM\n3Nua9Lzcl/FL19Ya5aDffZyY+QGlCD+gFOEHlCL8gFIVseE3/7tvF23T8fRyo9x6/7bztIxfpqFB\n1AVtcNnU8ZT5IlTr+ng2s4J4+byoC/PfX9V31vyZiP3P+mK7UV7ryK/smp0PIj79wuV75BZsaqm5\nKbn3wRrRpvUe+VVlkpj5AaUIP6AU4QeUqog1f99Dq43y5bcdEG1a19hb4/ulJtTKygTX/KmqcUbZ\nGxsVbVrXb02s/zBO3mu+mDXl93LfptB50NZwhCMPr
 xZ1zY9vTqw/b6e5L9F6T2JdhcbMDyhF+AGl\nCD+gFOEHlKqIDb+mJ8yNmJEnZJtM4xSjXDhxMskhGfLdPaIuM2O6qCsc7Rd1UQRt8JWboA0+v66f\nmi8izXm0+M/EJcnNvVDSGVF18m7z3yPMv+FFDSHRpwMoW4QfUIrwA0pVxJo/jP7bFxrlxqftrR+D\nxLW+v1Rk58wWdUmt8YNOFup7wFxPt7x+XLQp7OlIZDyO4ziZyebJQYe+uVi0mfWY3X0IZn5AKcIP\nKEX4AaUIP6BUyn89VJLcvtyleb42UEbSTZ3ybPugdkkPBEB5IvyAUoQfUMrqSz5rW+SpqkEfOCSl\nrds8HTVwPBa19e4SdaUcU7mNx3HkmMptPI5Tfr+zsJj5AaUIP6AU4QeUIvyAUqX/qs+NeklTEalQ\n7zlUpEzrfKM81jxRtIl6131SMtOmibrCsWOxPDu95EqjfOTGyaLN1PfPGeWqk8Oijbs7uSu9spfN\nMspefcBx7wXXLO7dl9h4HIeZH1CL8ANKEX5AqZKv+Yduu94oNzx0SLS5fcYOo/ziopbExjP4JXM8\nE/7yTmJ9RVXo2G+U08kdQBOboPX9mvfMdfema8ZHera7a49RnhHivRe3eJNY5Q93W+6xOGZ+QCnC\nDyhF+AGlCD+gVMk3/Ope222UR/5+TrR50Sm+wZdtbjLK+b6jkcbj3+BLT5gg2riDg5GenZTj31gl\n6qb+rrRHl4fx7O7VRnmBk9yLSanqaqPsjYyINkO3Xy/qav9mb8P3xNfN32PjM1zXBSABhB9QivAD\nSpV8ze/61l7e6mtFm4Efmi+DDG6ZKtpc9jPfVUcxfdgTtL5P19QY5dn/ln11rZAfjiQlaH2fWmZe\nB+Vtb7c1nNBq34v2Uk8UYo0f8Pdhc30fJOk1vh8zP6AU4QeUIvyAUoQfUKrkG35+qbffE3VTPmve\n8jXFCfiMzeLJPe4580WkrhXn
 aVhCp66oN8qTtp+nYQkNXi1f6LIlMz3gZKGj/SUYSekw8wNKEX5A\nKcIPKEX4AaXKbsPP8byiTfxHVzuO4wwubDTKNa9si21I5S47U371OOn5LSUYycdYeY2oWvSdLqOc\n0CHugYI290bXLRd14zZeun9HzPyAUoQfUIrwA0qlvBBr7Li4fTl7nQFKpZs6Q73xxswPKEX4AaUI\nP6AU4QeUsvqSz9qWJTa7E9p6zUvcym08jlPaMZXbeByH31kxQeMJi5kfUIrwA0oRfkCp8vuwB4Z0\nba2oc4eGSjCS//NffTV8szxuva7dd13a6Jhok+/pjXVc5SyzeKFRLrTvFW1SWTOOXj6f6JiY+QGl\nCD+gFOEHlCL8gFIVueH30cZ5oq5u3YESjOT8hj8vz/Me//LWC39QJhNL/5H6Pg//vXc1r8hnJ7tV\n9fG8T8qXblJvmS/DdPxhmWjTeu+OgIdd+Ieo2XlzRF0+YINPdJXwBp8fMz+gFOEHlCL8gFIVseZ3\nbzDXcHXron/MYEv3bfIs2tzLF/4c9+xZUZeury/aJs41fqXxr+8dx3E++vJKo9x6T3KnG+cPdIm6\n7KyZRrnQPEW08ba9n9SQAjHzA0oRfkApwg8oRfgBpSpiwy/9prmB8+GPVos2s3+y2dZwBG+1/Kot\nd/f2xPrzb/BlcvKlp6GceX1Z9at2r51y1yw1yulNO63271f3UvENvlNfWyXqJv/p7Vj69wbNLzG9\nbT2xPPdiMPMDShF+QCnCDyhVEWt+v1Ku74OkNu8WdZkFc0VdYd/BRPovdMqPmkaXTTfK1aJFskq9\nxo8irvV9kMLAQNE2vY+Ye1ktv07275yZH1CK8ANKEX5AKcIPKFURG35jn77OKFf9890SjSS8Dx6Z\nJupa1yez4Ze+apGoq/9zcl+tVaLuH5ibabMes7xpnDZPZMrUTRBNkt7g82PmB5Qi/IBShB9QKuVF\nOJ00Krc
 vZ68zQKl0U2cqVLukBwKgPBF+QCnCDyhF+AGlrL7ks7ZFXqNkU1uveSJQuY3HcUo7pqDx\nrJt9naizea2U+J3NXCobWdy0Dvo3unXRjUbZHT5nazjOxkPRj2hn5geUIvyAUoQfUIrwA0qV/Ku+\ndE2NUT7xFbmhkx0xN3Rqj46KNplNvqO0XHlXXhQjtywXdbVdp8yKMbkBltSRXY7jOKnlVxvl0QZ5\nSFdcXz4mubmXmTzJKBdOnS7+QwGbe6nrrjKbvPufixrXhfIK5t9aespk2eajQaPsDg6KNrYx8wNK\nEX5AKcIPKFXyNb97znwhouE5eXyyf41r8x7z6tfkNVfx7CZE5//vr7Lcf8/3zVNxZv4i2gk0odb4\nIWR6jhtle68gBSsc7S/aJrN4ofy59r1JDOe8mPkBpQg/oBThB5Qi/IBSJd/wCyPMBt/pO1ca5Ukv\nJHd0dXbu5Ub51PJm0SbMffBxybTOF3XDcxuMcnX/sGjj7WyP1F/UDb6k5I/0GeXsrJmyTXePreGI\nF9ccR25s297cC8LMDyhF+AGlCD+gVEWs+bPz5hjl3nUtos30J+2tQwvdR4xy3cFD1voOUujYL+rG\ndZjl/b9cJdrM25nUiErL5vo+iH997zjyyrl//fEZ0WbVI+uN8sQNye4bMfMDShF+QCnCDyhF+AGl\nKmLDL3+gyyhPf7IrsJ0t3pg8Sajczfue/FpSs8y0aaKucOxYYv35T1YKOqJ9omPvxTDHYeYH1CL8\ngFKEH1CqItb8YWSubDXKhT0d52kJG/ofME/7sfkSVhhJru8rBTM/oBThB5Qi/IBShB9QKuVZvNvc\n7cvZ6wxQKt3UmQrVLumBAChPhB9QivADSll9ySfoYwab2np3GeVyG4/jlHZM5TYex6mM39mti240\nyoUzZ2wNJ3A8YTHzA0oRfkApwg8oRfgBpS6Zr/pgT+FTnzDKPWvk9VTnmseM8oINedEm
 val0Z4en\nli0Wdd72aNeXuSMjFzscx3EcJ9s0wyh7Q/KKtTg3E5n5AaUIP6AU4QeUumTW/IcfNU+Ouezn0U6O\nGbtpmVGe8mN5FdeejeapQUF9ZefMFnX5rg8jjancZN7YYZRnvxHtOf3f8p3285t4Tvs597kVom7C\nvgGjXAhY36eqxok6myc15/uOGuUDQVesxXgKMzM/oBThB5Qi/IBShB9Q6pLZ8Jvz5AdGuRDxOVWv\nbzfKZ1+XbS5zjhd9zqWyuRfVvidWGuXUdHln/fyvJnOcd80/too6/9/DsfVyM23aU+V1pVnumaOi\nLurfdRBmfkApwg8oRfgBpSpyzW/zBZqgvgavMD/AqH5tm2iTWn61qPO2vR/LmPzXSw/cPF+0mbjB\n7nXPfgseKt5/trnJKOeP9CU1HMdbfa1RDlrfZxYvFHWF9r2JjamY/35bXiOee/BAbM9n5geUIvyA\nUoQfUIrwA0pV5IZf0ObeifvMlzYan43nhY2gvqpDbC66VfL/q6HuUArBf7f8xA2Vedd8kht8fqnN\nu4u28aoyFkYSXu7BdxJ9PjM/oBThB5Qi/IBShB9QqiI3/ILEtcEXxpk7zC/W+m6Sx1K33veureGU\npXR9vVF2z54t0UiCDdwlv+preK68vupLGjM/oBThB5Qi/IBSKc/zrHXm9uXsdQYolW7qDPU+GTM/\noBThB5Qi/IBShB9QyupLPmtbltjsTmjr3WWUy208gE3M/IBShB9QivADSlXkhz3ZuZeLuvzBQyUY\nCVC5mPkBpQg/oBThB5Qi/IBSZbfhl66tFXXu0JBRTnJzz3+nW5gjn4OMrlsu6sZtlHf6AaXCzA8o\nRfgBpQg/oFTZrfn96/sgJ+6XJ682Ph3Pyav+Nb7/DnnHCXfNVO3uw/Lnog8LiB0zP6AU4QeUIvyA\nUoQfUKrsNvzCCNrcO32neYXWpBe2xNKXNzxctI17gzwRKP8mp/S
 gvDHzA0oRfkApwg8oVZFr/iBu\nNtQNRRescOp0Is8FSo2ZH1CK8ANKEX5AKcIPKFWRG36ZqY2iruG5eL7qiyId8EJP0BgLx0/YGA4Q\nCjM/oBThB5Qi/IBSKc/zrHXm9uXsdQYolW7qDPXGGzM/oBThB5Qi/IBShB9QyuqGH4DywcwPKEX4\nAaUIP6AU4QeUIvyAUoQfUIrwA0oRfkApwg8oRfgBpQg/oBThB5Qi/IBShB9QivADShF+QCnCDyhF\n+AGlCD+gFOEHlCL8gFKEH1CK8ANK/Q/zQX1soXEu2gAAAABJRU5ErkJggg==\n",
+      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAP4AAAD8CAYAAABXXhlaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAADeFJREFUeJzt3W1sHMUdx/Hdu3NsEuzEECcXOyQOid0kQHDqJCQUqVVF\nSUqlFgm16oPKQxEtUFQKUktLS1ErIVJRlZKqQFupwBue1Qf1IUlLoa0gzyEJMSTkTEMebOw44JAn\nbHy325fV7H/RXU67s3v+fz/vZjS3M7nzL6MZ7c66vu87AHTJJD0AAPYRfEAhgg8oRPABhQg+oBDB\nBxQi+IBCBB9QiOADCuVsdvap7BfEbYLuhAnW+l+3f7NRXtnaZa3vMOv7d4q6JMeUtvE4jhxT2sbj\nOOn7zTL5glvuc8z4gEIEH1CI4AMKEXxAIaube07II8D+6OgZXybTtVDUuX1DRrk0NCTajFd9d14q\n6kYvPm2U517TI9r4xWJsY4Ip19ZqlPuubhdtpq/ZYGk0zPiASgQfUIjgAwrZXeNHxNv5eqL9v3/V\nMqN8do/cTyj17rc1HKftp+XXhoN/mi/qpn1ubxzDqdj+1SuM8pzvbYzkutnmZlF36MYFRnlKb0m0\nmfj7zaIuKr03zTbK7XfbW8+HYcYHFCL4gEIEH1CI4AMKpW5zL9PYKOq8EyfKf3D5IrO86dWIRiSd\naDO/tsEledGm/Yf2NvcqYXsjb/hac+Ou+XG5cTc2/YNY+u67boGoO3f3mFGuX7s1lr4/zLxHDhjl\npG+dYsYHFCL4gEIEH1AodWv8itbzIYqT6oxynP+wab8yb74oPNYdY2+1KbimP/n5S0SbzuvjuWEm\n/0CyN8eEKfb1G+V9jywTbTpv2mJrOMz4gEYEH1CI4AMKEXxAodRt7lUr98/tifXd+udx8zXG5q77\nHhd1a56VTwxq0bQn2b8ZZnxAIYIPKETwAYVqcnHqr
 7hY1Lkbd1nrv7DGvBml41vxndwyXtz7g+tE\nXaOzKZa+cu2zRN3JC80HqRr+Yu9mGceRJ0PnH+QEHgCWEXxAIYIPKETwAYVcP+S1VnHxBjrsdQYo\nlckX3LJtbAwEQLoQfEAhgg8oZPUGnpWtXTa7E9b37zTKaRuP4yQ7prSNx3FCfrOZ8rQjN1N2SRuZ\ndQe3ibqVbYvNCov7ZmG/WSWY8QGFCD6gEMEHFCL4gELJP52XyZplT763PJLrVsmtmyDq/LHyr36q\n9nPjVXZBh6wcetcolo6+U/Y6YRt5ftF8IZWbk3/W++9ZapTzm+XfWdVP7FWxmXf06ytE3ekZ5r9t\n9mp5qpQ/OnrGfYVhxgcUIviAQgQfUCj5NX7KHblB3jDS8oh85XOQu3CuqPN37YlkTNl5c4xyqTdd\nr+QOU9pTEHVLd5rr7K1d0ezLZNrPE3Xtd5u/WXbquaJNRLtLFZn6m/J/Q3HeBsSMDyhE8AGFCD6g\nEMEHFErd5p7bfYGoG8lPNMr1f90q2mQWma9j8nrkZlI18i8OibrgJtDRb8ibMab+uvzmTdWOHS/b\nJJefbpSLA4NxjaZqf3hzkVGe6bwWyXUr2ex0Gxpk3ZILRZ2/rSeSMaUNMz6gEMEHFCL4gELpW+Pv\nOyjq6refKPu599sazc9EtDQrvdEr6oZuNtf0LQ/HuJ4PEXyYZexyeZOR83xyrw0PE/bas/Zvm/+O\nomgRndErzYd0nL/JfaLRRa2irj6uAVXCDTlZKKLTfZjxAYUIPqAQwQcUIviAQqnb3PNOlN/Iy82W\nT1+5/9hhlON8ssn2Zl45mWL630xWuLFO1HV+7bC1/s96YbdR9kLa1Ids+CUqxmO6mfEBhQg+oBDB\nBxQi+IBCqdvcq8TYTHlsknuoP5a+sgs7RZ1/oM8oe6dOxdJ3pbL/eiXR/isx7UW5uWeTNzJilEc/\nvVS0qV+bss29GDHjAwoRfEAh
 gg8o5PoW3+XtDXSk/04ToMZl8oWQx/oCbWwMBEC6EHxAIYIPKETw\nAYWs3sCzsrXLZnfC+v6dRjlt43GcZMcUNp5Vs5YkMJL/W3dwm1FO428mvqNsNO8ArMS6/Zur+hwz\nPqAQwQcUIviAQjX5kI522aYmo1w6Xv6VWtXyixUcep2Ra9pD37/EKE8clPdutTxtnoFeyelLaSS+\no5DvzK03D+o+fLs8Ev2sI+Z3dM7v4jvpiRkfUIjgAwoRfEAhgg8oVJObexdul/9f9XSHHZicnMKD\ny0Vdx22bIrn28GcWGuWmJ0OuG9xw80qR9B0q5Nrn3buh/MfiGEuF5m5tEHX7b2gXdd6reyPpz51/\nvlFuW13++4kTMz6gEMEHFCL4gEI1scbf99vAiajd6T8N9dnPrhF1d922LJJrT9l9zCiHrZUHv2ne\nQDP9l8muKdPmzaUjoi7bPBhbf96uPbFduxrM+IBCBB9QiOADChF8QKGa2NzrvDH9m3lBX3r6NlE3\nx4nmaSuvx7ypZOD2S0Wb/ANs5p2p0vCwtb68jy8WdZl/77DWPzM+oBDBBxQi+IBCNbHGT7t9D8sb\nczpvju/0lKBTbel6QAnl2VzPh/afaO8AEkHwAYUIPqAQwQcUqonNvRNfNE+zaXwqmpNsovKJxfLJ\nq/4Y+8tOmWyUOx47Jtqw3WcKHknu+/K47ziP987lpxvl4kB8TwJWghkfUIjgAwoRfEAhN2ytExdv\noMNeZ4BSmXzBLdvGxkAApAvBBxQi+IBCBB9QyOoNPCtbu2x2J6zv32mU0zYex0l2TGkbj+PUxm+2\nao55lLmbsxertYWXq/ocMz6gEMEHFCL4gEIEH1CoJp/OO90i/79qfabXKJcGj8Q2nuFrVxjlKb3v\nizbuy3ITKC5xHq+dbW4Wdd7JU0bZH/ugqmvnZuSNcunou1VdR8hkZZ1XiubaIfwPzH+/PzoaW19R\nYcYHFCL
 4gEIEH1CoJtb4wRN3GkPaxLeCkyZ+5W2j7F7xlsXepTS+Liu47xA2xuLbA0bZrZsQSd+H\n77xE1M28L33fUZKY8QGFCD6gEMEHFCL4gEI1sbkXlF3YKepKr++z1n99YDPvoQMviTa3zL7M0mgc\nx7/0YlHnbthllINHcjuO45SOvRdJ/8VPdou6JDccp/Ta3OqtjNt9gVF+r1NuUTc9ae/YeGZ8QCGC\nDyhE8AGFanKNH7aeD74iqXT8uK3hONfuuUbUTXL+a63/4HrecRwn02iuIaNaz4fJvbA9tmtX4+xn\nN4u6gz8ybyia9RO7exCZt8ybvpq2v2a1/yBmfEAhgg8oRPABhQg+oFBNbu6FsbmZF7xhZdKqdG1u\nOY7dI57DTrzJzQi8D76vX7SxOcYZm6o7JSgqpXciOl0oIsz4gEIEH1CI4AMKjZs1vk1XPPgfo/zC\nRZMSGsmHKw0P2+ss7ARbzyv/OTeeeSds76Du79ti6atabn29qLN5Oi8zPqAQwQcUIviAQgQfUMj1\nfd9aZ95Ah73OAKUy+YJbto2NgQBIF4IPKETwAYWs3sCzsrXLZnfC+n7z1dVpG4/jJDumsPGsmrVE\n1IXdfBKXtYWXjTK/mSlsPJVgxgcUIviAQgQfUIjgAwrxdJ4S1T4N5heLIRcz5wu3Tv4ZDT/XapZ3\ntIg2c3+21yh7J0+VHU9Ush+ZJ+pKb/TG16Fr3lNz6uplokndSfOJxgnrtsY2HGZ8QCGCDyhE8AGF\nxs0av/fny43yvDvie+XwkVvN1zG1vCLXprk9B0Wd1VNxAuI83cU7fVrUTb7SXC9PduT6+dB3zO+x\n7RfxnZJz4MdmX7Pvka/QyrbIfYjS0FA0Awg8DDfpOfmar+Lzs4xy5vB80cbr2SvqqsGMDyhE8AGF\nCD6gEMEHFBo3m3sTzovn5o9jX10h6mY89YZRduvqRJtix0x5sS3RbO65Sy8yyv7W3aKN
 d5n5xFjm\npeqe4opT6/2BDba6CbH1FdzMy+WnizbFgcHY+q9E7nJzQ9jvviC2vpjxAYUIPqAQwQcUGjdr/Dk3\nHDDKIS91qkrzM6+IulLgZphsx/miTe7oCVEX8rhLVdzdBaMcdnSxzTV9dspkUVc69p61/qux97tz\nRN28O5Jd4wf5O6K5WScMMz6gEMEHFCL4gEIEH1CoJjf39j0kTy/pvGVLLH2FPdUWvIHGOSg3hYqD\nR2IZj+M4jjcyYpSzU88VbUpH34mt/yB/pLon/8LeY2/L/PvfEnVRbb5Gxotqi1pixgcUIviAQgQf\nUIjgAwrV5ObetI3ZRPvP3X/UKI/e3SbaZGLc3AvyZudlpcXNveBmY8Vce/NObqb5GxUP91nru1KZ\nhgajXPX3WklfsV0ZQGoRfEAhgg8o5Pp+2LNd8fAGOux1BiiVyRfcsm1sDARAuhB8QCGCDyhE8AGF\nrN7As7K1q3yjGK3vN4+jStt4AFuY8QGFCD6gEMEHFKrJh3TcxfLVQv6O1xIYCVCbmPEBhQg+oBDB\nBxQi+IBCNbG5N/DHBUY5f1X6N/LevX6FqDvn

<TRUNCATED>


[14/15] incubator-singa git commit: update conda build files for py3

Posted by wa...@apache.org.
update conda build files for py3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/57dbe429
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/57dbe429
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/57dbe429

Branch: refs/heads/master
Commit: 57dbe429ecbcd5745c78f3a6371dde6ec0488335
Parents: 01b7a74
Author: wangwei <wa...@comp.nus.edu.sg>
Authored: Mon Jul 31 14:32:50 2017 +0000
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:17:17 2017 +0800

----------------------------------------------------------------------
 cmake/Dependencies.cmake |  5 +++--
 tool/conda/build.sh      |  2 +-
 tool/conda/meta.yaml     | 24 ++++++++++++++++++------
 3 files changed, 22 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/57dbe429/cmake/Dependencies.cmake
----------------------------------------------------------------------
diff --git a/cmake/Dependencies.cmake b/cmake/Dependencies.cmake
index 180732b..07736a0 100644
--- a/cmake/Dependencies.cmake
+++ b/cmake/Dependencies.cmake
@@ -129,8 +129,9 @@ IF(USE_PYTHON)
         FIND_PACKAGE(PythonInterp 2.7 REQUIRED)
 	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
     ELSE()
-        FIND_PACKAGE(PythonLibs 3.0 REQUIRED)
-        FIND_PACKAGE(PythonInterp 3.0 REQUIRED)
+        set(Python_ADDITIONAL_VERSIONS 3.6)
+        FIND_PACKAGE(PythonLibs 3 REQUIRED)
+        FIND_PACKAGE(PythonInterp 3 REQUIRED)
 	FIND_PACKAGE(SWIG 3.0.10 REQUIRED)
     ENDIF()
 ENDIF()

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/57dbe429/tool/conda/build.sh
----------------------------------------------------------------------
diff --git a/tool/conda/build.sh b/tool/conda/build.sh
index 2716452..7bd9023 100644
--- a/tool/conda/build.sh
+++ b/tool/conda/build.sh
@@ -16,7 +16,7 @@
 #
 
 # to compile swig api files which depdend on numpy.i
-export export CPLUS_INCLUDE_PATH=`python -c "import numpy; print numpy.get_include()"`:$CPLUS_INCLUDE_PATH
+export export CPLUS_INCLUDE_PATH=`python -c "from __future__ import print_function; import numpy; print(numpy.get_include())"`:$CPLUS_INCLUDE_PATH
 
 # to let cmake use the dependent libs installed by conda, including python
 export CMAKE_PREFIX_PATH=$PREFIX

http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/57dbe429/tool/conda/meta.yaml
----------------------------------------------------------------------
diff --git a/tool/conda/meta.yaml b/tool/conda/meta.yaml
index 2342e4a..bb65ce4 100644
--- a/tool/conda/meta.yaml
+++ b/tool/conda/meta.yaml
@@ -3,7 +3,7 @@ package:
   version: "{{ GIT_DESCRIBE_TAG }}"
 
 source:
-  git_url: https://github.com/apache/incubator-singa.git
+  path: ../../
 
 
 build:
@@ -15,9 +15,12 @@ build:
 
 requirements:
   build:
-    - swig 3.0.2
-    - openblas 0.2.19
-    - protobuf 3.2.0
+    - python 2.7* [py27]
+    - python 3.6* [py36]
+    - numpy >=1.10
+    - swig >=3.0
+    - openblas >=0.2.10
+    - protobuf 3.2
     - glog 0.3.4
     - libgfortran 3.0.0 # [osx]
     - gcc 4.8.5 # [linux]
@@ -25,8 +28,10 @@ requirements:
     - numpy 1.12.0
 
   run:
-    - openblas 0.2.19
-    - protobuf 3.2.0
+    - python 2.7* [py27]
+    - python 3.6* [py36]
+    - numpy >=1.10
+    - protobuf 3.2
     - glog 0.3.4
     - libgfortran 3.0.0 # [osx]
     - libgcc 4.8.5 # [linux]
@@ -35,6 +40,13 @@ requirements:
     - flask >=0.10.1
     - flask-cors >=3.0.2
     - pillow >=2.3.0
+    - libgcc 4.8.5 # [linux]
+
+test:
+  source_files:
+    - test/python/*.py
+  test:
+    - python run.py
 
 about:
   home: http://singa.apache.org/


[12/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/bd5a8f8d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/bd5a8f8d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/bd5a8f8d

Branch: refs/heads/master
Commit: bd5a8f8d5e99db1fead1eb539e7afe91d1feafb6
Parents: bfeb612
Author: Moaz Reyad <mo...@gmail.com>
Authored: Sun Jun 25 19:35:00 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:16:00 2017 +0800

----------------------------------------------------------------------
 doc/en/docs/notebook/cnn.ipynb | 592 ++++++++++++++++++------------------
 examples/cifar10/predict.py    |   2 +-
 examples/cifar10/train.py      |   2 +-
 python/singa/net.py            |   1 +
 python/singa/snapshot.py       |   3 +-
 5 files changed, 297 insertions(+), 303 deletions(-)
----------------------------------------------------------------------



[13/15] incubator-singa git commit: SINGA-290 Upgrade to Python 3

Posted by wa...@apache.org.
SINGA-290 Upgrade to Python 3


Project: http://git-wip-us.apache.org/repos/asf/incubator-singa/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-singa/commit/ff1806b8
Tree: http://git-wip-us.apache.org/repos/asf/incubator-singa/tree/ff1806b8
Diff: http://git-wip-us.apache.org/repos/asf/incubator-singa/diff/ff1806b8

Branch: refs/heads/master
Commit: ff1806b8cba844e05499a2af1626364c5ec940cb
Parents: bd5a8f8
Author: Moaz Reyad <mo...@gmail.com>
Authored: Wed Jul 12 10:52:51 2017 +0800
Committer: Wei Wang <wa...@comp.nus.edu.sg>
Committed: Thu Aug 3 18:16:00 2017 +0800

----------------------------------------------------------------------
 doc/en/docs/installation.md | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-singa/blob/ff1806b8/doc/en/docs/installation.md
----------------------------------------------------------------------
diff --git a/doc/en/docs/installation.md b/doc/en/docs/installation.md
index d60e572..79996a4 100755
--- a/doc/en/docs/installation.md
+++ b/doc/en/docs/installation.md
@@ -105,10 +105,13 @@ The following libraries are optional
 2. run `cmake [options] ..`
   by default all options are OFF except `USE_PYTHON`
 
-    * `USE_MODUELS=ON`, used if protobuf and blas are not installed a prior
+    * `USE_MODULES=ON`, used if protobuf and blas are not installed a prior
     * `USE_CUDA=ON`, used if CUDA and cuDNN is available
     * `USE_PYTHON=ON`, used for compiling PySINGA
     * `USE_OPENCL=ON`, used for compiling with OpenCL support
+    * `PYTHON2=ON`, used for compiling with Python 2 support. (The default is Python 3)
+    * `PACKAGE=ON`, used for building the Debian package
+
 3. compile the code, e.g., `make`
 4. goto python folder
 5. run `pip install .`
@@ -258,6 +261,17 @@ To build SINGA with OpenCL support, you need to pass the flag during cmake:
 
     cmake -DUSE_OPENCL=ON ..
 
+#### Compile SINGA with PYTHON2=ON
+
+The default Python version for SINGA is 3. SINGA can be built for Python 2 by setting PYTHON2=ON.
+
+#### Compile SINGA with PACKAGE=ON
+
+This setting is used to build the Debian package. Set PACKAGE=ON and build the package with make command like this:
+
+    $ cmake -DPACKAGE=ON
+    $ make package
+
 ### Compile SINGA on Windows
 
 For the dependent library installation, please refer to [Dependencies](dependencies.md).