##// END OF EJS Templates
Merge pull request #6045 from minrk/nbformat4...
Thomas Kluyver -
r18617:482c7bd6 merge
parent child Browse files
Show More
@@ -0,0 +1,21 b''
1 """NotebookNode - adding attribute access to dicts"""
2
3 from IPython.utils.ipstruct import Struct
4
5 class NotebookNode(Struct):
6 """A dict-like node with attribute-access"""
7 pass
8
9 def from_dict(d):
10 """Convert dict to dict-like NotebookNode
11
12 Recursively converts any dict in the container to a NotebookNode
13 """
14 if isinstance(d, dict):
15 return NotebookNode({k:from_dict(v) for k,v in d.items()})
16 elif isinstance(d, (tuple, list)):
17 return [from_dict(i) for i in d]
18 else:
19 return d
20
21
@@ -0,0 +1,308 b''
1 {
2 "cells": [
3 {
4 "cell_type": "markdown",
5 "metadata": {},
6 "source": [
7 "# nbconvert latex test"
8 ]
9 },
10 {
11 "cell_type": "markdown",
12 "metadata": {},
13 "source": [
14 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
15 ]
16 },
17 {
18 "cell_type": "markdown",
19 "metadata": {},
20 "source": [
21 "## Printed Using Python"
22 ]
23 },
24 {
25 "cell_type": "code",
26 "execution_count": 1,
27 "metadata": {
28 "collapsed": false
29 },
30 "outputs": [
31 {
32 "name": "stdout",
33 "output_type": "stream",
34 "text": [
35 "hello\n"
36 ]
37 }
38 ],
39 "source": [
40 "print(\"hello\")"
41 ]
42 },
43 {
44 "cell_type": "markdown",
45 "metadata": {},
46 "source": [
47 "## Pyout"
48 ]
49 },
50 {
51 "cell_type": "code",
52 "execution_count": 3,
53 "metadata": {
54 "collapsed": false
55 },
56 "outputs": [
57 {
58 "data": {
59 "text/html": [
60 "\n",
61 "<script>\n",
62 "console.log(\"hello\");\n",
63 "</script>\n",
64 "<b>HTML</b>\n"
65 ],
66 "text/plain": [
67 "<IPython.core.display.HTML at 0x1112757d0>"
68 ]
69 },
70 "execution_count": 3,
71 "metadata": {},
72 "output_type": "execute_result"
73 }
74 ],
75 "source": [
76 "from IPython.display import HTML\n",
77 "HTML(\"\"\"\n",
78 "<script>\n",
79 "console.log(\"hello\");\n",
80 "</script>\n",
81 "<b>HTML</b>\n",
82 "\"\"\")"
83 ]
84 },
85 {
86 "cell_type": "code",
87 "execution_count": 7,
88 "metadata": {
89 "collapsed": false
90 },
91 "outputs": [
92 {
93 "data": {
94 "application/javascript": [
95 "console.log(\"hi\");"
96 ],
97 "text/plain": [
98 "<IPython.core.display.Javascript at 0x1112b4b50>"
99 ]
100 },
101 "metadata": {},
102 "output_type": "display_data"
103 }
104 ],
105 "source": [
106 "%%javascript\n",
107 "console.log(\"hi\");"
108 ]
109 },
110 {
111 "cell_type": "markdown",
112 "metadata": {},
113 "source": [
114 "### Image"
115 ]
116 },
117 {
118 "cell_type": "code",
119 "execution_count": 6,
120 "metadata": {
121 "collapsed": false
122 },
123 "outputs": [
124 {
125 "data": {
126 "image/png": [
127 "iVBORw0KGgoAAAANSUhEUgAAAggAAABDCAYAAAD5/P3lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
128 "AAAH3AAAB9wBYvxo6AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURB\n",
129 "VHic7Z15uBxF1bjfugkJhCWBsCSAJGACNg4QCI3RT1lEAVE+UEBNOmwCDcjHT1wQgU+WD3dFxA1o\n",
130 "CAikAZFFVlnCjizpsCUjHQjBIAkQlpCFJGS79fvjdGf69vTsc2fuza33eeaZmeqq6jM9vZw6dc4p\n",
131 "BUwC+tE+fqW1fqmRDpRSHjCggS40sBxYDCxKvL8KzNBaL21EPoPB0DPIWVY/4NlE0ffzYfhgu+Qx\n",
132 "GHoy/YFjaK+CcB3QkIIAHAWs3wRZsuhUSs0CXgQeBm7UWi/spn0Z+jA5yxpEfYruqnwYllRic5a1\n",
133 "MaWv8U5gaT4M19Sx396IAnZLfB/SLkEMhp5O/3YL0AvoAHaKXl8HLlZK3QZcpbWe0lbJDOsaHuDU\n",
134 "0e4u4JAy2wPk/C1JzrKWArOQ0fUtwH35MOysQxaDwbCO0NFuAXoh6wPjgQeUUvcqpUa0WyCDoQls\n",
135 "CIwBjgfuAV7KWdY+7RWpmJxlXZezrEdylvXxdstiMKzrGAtCYxwI/EspdZbW+g/tFsbQ67kQuBHY\n",
136 "FNgseh9FV6vCbUAeWBC9PgBeq2EfS6J2MQOBrRDTe5KdgAdzlvW1fBjeUUP/3UbOsoYBE6OvG7VT\n",
137 "FoOhL9Af+BUwFLkZpV+DaY6V4UPkRpb1+ncT+m8nGwK/V0oN01qf025hDL2XfBi+DLycLMtZVo6u\n",
138 "CsKfGnSq8/NheEpqHwOBEcDBwJnAsGhTP2ByzrJG5cPwnQb22Sy+0G4BDIa+RH+t9dmlNiqlFKIk\n",
139 "JJWGi+jq5JPmq8BbJJQArfXqpkncczlbKbVQa/3rdgtiMNRCPgxXAK8Ar+Qs63LgXmDvaPPGwPeA\n",
140 "H7VJvCRfbLcABkNfouwUg9ZaAwuj178BlFLvVejzgR4WFviM1npcuQpKqf6IyXIjxLS7GzAWuUnu\n",
141 "XsO+fqWUellr3ZBJdq/jr9+BDn1uve07O9Rz0y6f8PtGZGgWe53oT6SBkZ/q1/nHZy47aloTRTKU\n",
142 "IR+Gy3OWNR6Zxtg0Kv4KRkEwGPocxgcBiCwcsSI0F5iOhF+ilPok8C3gVGS+thK/VErdrbWuO2ys\n",
143 "s/+aLZTuOKbe9krrIUCPUBB0B+PQ1P1bdKe6EzAKQgvJh+GbOct6gkJkxM45y+qXDIWMHBhjBWJe\n",
144 "PgyDWvaRs6zPIVObAG/nw/DpEvUGAp8E9gGGJzbtl7Os7cvs4skqp0V0Yl8jgcOBjyMDhbmIZeWl\n",
145 "fBg+UUVfReQsayhwELAnsAXi6/E28BxwTz4MP6iyn92RaSCA+/NhuCwqXx9R4MYhU0MfRTK/AjyW\n",
146 "D8MFGd0ZDFVhFIQKaK3/BXxfKXUlklTq0xWafAI4Driyu2UzGLqRlygoCArYHJif2H4gcFb0+Z2c\n",
147 "ZW2bD8NV1XScs6yNgH8g/jsAPwCeTmzfFPgjYsnbiez71MUVdnMQcF8V4nyUs6whwB8QX4+0s2Ys\n",
148 "0yPAt/NhGFbRZ/wbzgO+DaxXotqqnGX9GbigCkXhf5CBCsDngYdzljURGQhsWqLN+znL+iFwdT4M\n",
149 "dYk6BkNJTJhjlWitQ2Bf4P4qqv848t8wGHor6Yd9+ruHJFkC2BI4rIa+D6egHKwmstYlGAxMQCwH\n",
150 "rRjEPI5ER5S7ZvcFXsxZ1phKneUsawSi8HyH0soB0bbvAM9Ebaplt5xlnYkct1LKAYiFZhJwSQ19\n",
151 "GwxrMRaEGtBar1RKfRX4JxIzXortou3PN1mE+YgJsSwaeoLHOQCqUy3QSr9eqZ6G/gq2aYVMhqrY\n",
152 "OfF5FeJwvJZ8GM7JWdY/gC9HRS7wtyr7Pjrx+e6MqYC3KLbU7Qhck/h+FJIKvRRVjfSREXicU8EH\n",
153 "pgAvIIqLBZwGfC7avl5Uf29KkLOsTZCMq8npj9sQx89no37HIlaAODplNPBIzrJ2z4dhNVlaT0HC\n",
154 "XwFmIkrAC4if2PaIz8/3KCgn385Z1pX5MJxeRd8Gw1qMglAjWutlSqnTgUcqVP0SzVYQtP5mcMXE\n",
155 "SvvtUUy9YsK5QEWHy7EnTB6lOtSsFohkqEDOsgYAdqJoagkT9Z8pKAj75yzr4/kwnF2h748ho/GY\n",
156 "q9J1oqiKLj4JOctKK8Yz8mH4Yrl9VcnHkXVYTsyHoZ8WJWdZNyPThbF5/3M5yzowH4alpi9+T0E5\n",
157 "WA18Nx+Gf0zVeRG4KmdZ90R9bwCMRKwyX69C5h2j91uA4/JhuCSxbTYwJWdZtwNPIFbifsAFSISZ\n",
158 "wVA1ZoqhDrTWjyIjjXIc3ApZDIZu4ELgY4nvt5Wody8wJ/qsgBOr6HsihfvOfCRrY7v5dYZyAECk\n",
159 "GP0ISEZmZYZ55yxrB8SyEXNxhnKQ7Pt64H8TRUfmLGuXKmWeC4xPKQfJvp9CLCJlZTYYymEUhPq5\n",
160 "tcL2XVsihcHQJHKWtU3Osi5GnAZj5iKWgiKitRouTxQdl7OscnPu0HV64dp8GLY7R8pyxEGxJPkw\n",
161 "fBcZ9ceUSvN8IoV76upK/UZcgawcG3NKqYopfleFU+gDic/b5SzLWIwNNWFOmPqp5CG9sVJqPa11\n",
162 "VZ7dBkOL2D1nWcmcBkOR8MFtgM/QdTXJZcCR+TBcXqa/SYj5egAFZ8VMX4ScZe2FRPnEXF2z9M3n\n",
163 "3nwYVsrtAmK6/0z0uVR4ZXLtivvzYfhGpU7zYbgkZ1k3ACdHRQdWIQsUO3ZmkUzB3Q/xjaolLbeh\n",
164 "j2MUhDrRWr+mlFpJ+eV5hyIxz4YWs98Fj/Rf8uZbozo0/ZYt7D8rf9ORK9stUw/hU9GrEnMAp1R+\n",
165 "gph8GL4bzdNPiIpOorSzYtJ68FS1IYPdTLWp3hcnPm+Q3pizrA7E+TCmFn+aZN0dcpY1LB+G5e4b\n",
166 "y6rM8bA49X39GmQyGMwUQ4NUGnkMrbDd0A3sdeLk4z6cN+89pTtDTWd+gyErF+7pTv5eu+XqJbyK\n",
167 "TDHsmg/DJ6tsc2ni8+dzljUqXSGaevhmoqjIObFNVBzlV8kQug4W5tbQNl13WGatAv+poW+DoW6M\n",
168 "BaExPgC2LrO9nHWhpSilDqI4NPMhrfXUJvS9M/DfqeJXtdY3N9p3rex50uQ9lFKT6BrTvoFCXbTX\n",
169 "yZNfmnrZxHtbLVMP4xng74nvK5DzeD7wfIWRayb5MHwiZ1kzgF0oOCuemar2ZQoK8zLgr7Xup5t4\n",
170 "s0n9DEl9b0RBSPeV5q0a+jYY6sYoCI1RacnZ91siRXUMAH6eKnsYicdulDOAY1NlpzWh35pRqG9R\n",
171 "IuGN7uw4AfG878s8nw/DX3RDv5dScGY8NmdZP86HYXJaJzm9cHMp7/s2UHdK9BTpKaxBNbRN163k\n",
172 "t9Rux05DH8FMMTTGZhW2v9sSKarjbopNk/sqpUY30qlSahCSGS/JCuD6RvqtF6UpMm/HaHTJbYaG\n",
173 "mQzED/0umRVzlrUZhXwJ0HOmF5pJOlXyxzJrZbNt6rtZP8HQIzAKQp0opTZAlsItxTKtdTnv75YS\n",
174 "LR7lpYqrjV0vx2EUH4fbtdZtucnpMqOrDjPy6jYii8DkRFHSYnAEhem22cBjrZKrVeTDcCldTf/p\n",
175 "h345ksrEGprnF2EwNIRREOrnMxW2z2uJFLVxJcXmy2OVUo34ShydUda+EaIq7T2u0SZTY/eSdFY8\n",
176 "MGdZm0efk86J6/LCQUnFp5pIkZjkcvQz8mH4YZPkMRgawigI9VNp7v7BlkhRA1rr+RQneNqC2hba\n",
177 "WYtSajiS9z3JXLomaGktq/VllLIUdKqSWe0MjZMPwxlIel8Q/6Zv5CxrGIX8AJ10XU+hFtIRQ+UW\n",
178 "KWoXyYyTu+Qsa79KDXKWNRpJyx5zZ9OlMhjqxCgIdaCU6g98o0K1npBCNotLM8rcOvuagCRgSXKN\n",
179 "1rozq3IrCCZNfFkrfRjotWsCaJinUBODK51/tkuuPkTy/DoYOIDCfeb+fBjW4t2/lqhdcmRdbUri\n",
180 "VnILXS2HZ1WRvfAcCk61K4A/dYdgBkM9GAWhPr5F6XSrIBf6Qy2SpSaidSReShV/XilV7veUIj29\n",
181 "oOkB2fGmXT7x7sCbOGpFf7VZx4A1m0/znG2nehMyc+0bms7NFJxzxwH7J7Y1OvWUPG9/mLOsLRvs\n",
182 "r6lEaaOT0TtfBB5ITLWsJWdZg3KWdRNwTKL4wnwYzu9mMQ2GqjFhjjWilBqBpJYtx51a66UV6rST\n",
183 "S+maJz52VvxRdvVilFK7UbzexGNa67Kr+bWS6X+ekPYs79HkLGt34JOI+Xyz6D2d1vfMnGUdini6\n",
184 "L0C851/Oh2HD+SyaQT4MV+YsaxJyLm1Gwf9gAXBHg93/JNHHtsArOcuajCztPBDYCkkytBXg5sOw\n",
185 "5QmF8mF4W86yLgK+HxXtC8zKWVaALMm8CslHsicS7RFzL8VhyAZDWzEKQg0opbYE7qd8prPVdF2h\n",
186 "rSdyLfALYMNE2XFKqR/XsHbEURll62L4Wiv5PuBUqPPF6JXkLuCQbpGoPi4HfohYKGMHWD9axrlu\n",
187 "8mF4Z7RuwfioaDBwaonqRemQW0U+DH+Qs6xFwHnIFNwQsv+3mMnA8dHiVwZDj8FMMVSJUuow4DkK\n",
188 "a7GX4gqt9cstEKlutNaL6boULMho5tBq2iul+lH8IFuCmJcNfZx8GM6hOCFVU5THfBhOQHxfylkH\n",
189 "3gY+asb+6iUfhhcCewC3l5BlFbJk/P75MDwqlVTKYOgRKK1rizhSSk2h67ximo1abV5XSi2n9EIk\n",
190 "z2itx5XYVqnfQcjI7DiqW2XtfeCTUbRA3ex50nWfUrqjeJEcrfcLrpj4SCN9xyilxgDPp4of0Fof\n",
191 "UEXbg4B/pIqv1FrXnVNh7AmTR3V0qIwwRH1E4E28pd5+De0hZ1m/Bb4bfX0+H4Z7dMM+hgGjkDwC\n",
192 "S5FpjFk9bR4/Z1mDkGmF4VHR20g4Y3oxJYOhR9EXphg6lFLlVjFbH0mZvDGwCTAayCFe0ntTOZ1y\n",
193 "zDLgkEaVg1ahtX5BKfUU8OlE8ReUUjtorSstCduzch8YehSR5/6ERFG3nBvRuhE9frXUfBguA6pd\n",
194 "+Mpg6DH0BQXBBro7o+Ea4Bta66e6eT/N5lK6KggKOAE4u1QDpdTGFOdNmNkLf7uh+zgYcRQEMa+3\n",
195 "Je22wWBoDOOD0DhLgYla67vaLUgd3ETxglLHRXkeSnEExQ5gbQ9tNPQokis5TsqHoVlbwGDohRgF\n",
196 "oTECYHet9Y3tFqQetNYrKDb/DqN46eYk6emF1UhUhMFAzrImUEhDvgr4VRvFMRgMDWAUhPpYAvwf\n",
197 "8Bmte31+/8uQBEdJMjMrKqW2o5A2N+YfWusePw9s6F5yltWRs6zxwKRE8RXtyEVgMBiaQ1/wQWgm\n",
198 "eWTe/jqtdU9Zz74htNavKaXuAw5KFB+glBqptZ6Tqj6RQlrYGDO90AfJWdY5wNeQFQwHIAmetk5U\n",
199 "eZFCsiCDwdALMQpCed5AphEC4NF12BHvUroqCAoJ7TwvVS+d++BdJEmPoe+xKRLnn0UeODwfhm3N\n",
200 "RWAwGBqjLygIbwN/LbNdI1MGH6ReL/eWkMUmcDeSeGa7RNlRSqnzdZQoQym1C7Bzqt11NWReNKxb\n",
201 "zEMU6GHAesBiYCaSLOviaF0Cg8HQi+kLCsLrWuvT2y1ET0ZrvUYp5SG57mO2Bz4LPB59/2ZRQ5P7\n",
202 "oM+SD8OLgYvbLYfBYOg+jJOiIeZKxOs8STJiIb28daC1/lf3imQwGAyGdmEUBAMA0XTKraniI5VS\n",
203 "A6O0zOnloI31wGAwGNZhjIJgSHJp6vtgJBNlehW65cANLZHIYDAYDG3BKAiGtWitHwVeShV/muLF\n",
204 "uW7VWi9qjVQGg8FgaAd9wUnRUBuXAn9IfN8f+FyqTo/OfbDnSX8brDpXnqEUe2ropzQvdtDx66ev\n",
205 "GN9XolIMPQDb9T8LrBd4zsPtlsXQe7Bd/0BgQeA5QbtlMQqCIc21wC+ADaPv6WWu5wAPtVKgWtjt\n",
206 "6Os2XG/9jhdQjIzTQ2rFF9bQecy4E2/I9UQlwXb9LYDDK1R7K/Cc21shj6FxbNcfDjwGKNv1Rwae\n",
207 "83q7ZWo2tusPBb6ELGW9BbAICX99Gngs8Jx0hlZDBWzXHwvcC6ywXX9o4DlL2ymPURAMXdBaL1ZK\n",
208 "+ZRItwz8Jc6N0BMZMFB9GxiZsWnzTjrPAH7QWomqYgTF/h9pngC6RUGwXf+XwC2B50ztjv57M7br\n",
209 "XwJMCjxneo1NP0SWgAfJq7LOYLv+esAFwOkUL9wWM912/d0Dz+lsnWQ9A9v1BwEXAT8PPKfWVOML\n",
210 "kPVt3kNWQm0rxgfBkEWph5UG/tJCOWqnQ40ttUkrvWcrRamWwHOmAZsguSfGAi9Hmy5AUhgPAz7f\n",
211 "Hfu2XX8k8ENgx+7ovzdju/4uwP9D/peaCDxnCbANsF3gOYubLVu7sF1/AHAHcBaiHDwI/C+ywNsE\n",
212 "4KfA68BdfVE5iNgbOBmxqtRE4Dn/BoYDnwg8Z02zBasVY0EwFKG1fkEp9RTioJjkIa11zzaVarYq\n",
213 "vVFt2TpBaiN6oCwB5tiu/2FUPCvwnLTTaLM5oJv77800dGwCz1kXHXkvRNKydwI/Cjzn1+kKtuuf\n",
214 "i2TX7Ks0et681yxBGsUoCIZSBBQrCL0h98EbdW7rddiuPwoYFJu/bdffFNgL2BZ4DZgWKR5ZbRWS\n",
215 "2+KIqGiE7fpjUtXmlrtZRdaHscBAYDowM/CckimWbdffFfgw8JzXou/9kfUccojV5MXAcz4s0XYw\n",
216 "sCsymu8PzAVmBJ7zVqn9pdoPRVKF7wSsAN4EgqzRve36HcAoZDEqgO0zjs3rged8kGo3gOJ05ADT\n",
217 "s0bTkan+k9HXGaVGjNFxykVf81nH2Hb9Ich/MRJJeT291H9fL7brj6CwANfPspQDgOi3rijRx/rI\n",
218 "b8kB7wPPBZ4zL6Ne/JvfCDzn/WhufhvgvsBzVkR1dgN2AR4JPGduom38P7wXeM7c6FzfCfgU4iMR\n",
219 "lFLebNfPIefXzMBzikz8tusPQyx676bljmTeCfhyVLST7frp//TV9Dluu/6GwOhUvTWB58zIkjFq\n",
220 "sykyNfmfwHMW2K7fLzoWeyDTFPnAc14t1T7qYwNgT+Rc/wi5ZyT/N20UBEMRSqn+wNdTxQspTqTU\n",
221 "41BaP6yVOipzGzzSYnG6m6uBz0YPv7OQm3dytc35tuuflHZutF3/BuArwEaJ4p/QNdU2wGnAH9M7\n",
222 "jRSTG5CbS5LQdv2joymTLKYBzwHjbNc/DomW2TCxfbXt+sMCz3k/sa8RwM+Qh/X6qf5W2q4/CTit\n",
223 "zMN1OPB7CopQktW2658YeM5fEvXvRKZzBiXqZaWUPha4JlW2NfB8Rt0hiANfmjWIuf5jiLPfvVm/\n",
224 "AfmvbgNmB54zKrkheuD+Bjg11Wap7fpnBJ5TybelFk4E+iE+Fb+ptbHt+scg//nGqfJbgeMDz1mY\n",
225 "KN4UOZYX2q7fSWHhuNdt198ZOBc4MypbbLv+5wPPeTb6PiJqe5ft+ichx3WXRN8rbdc/OfCcrGis\n",
226 "R4ChiHKSlSn2f4BzkOvitMRvCKJ9DEzU9TPafwGZlkkyBvExSrKUrtdnmoOBycA5tus/iCyat3li\n",
227 "u7Zd/0rk2ihS1mzXPwT4E3LulaLTKAiGLL6EaMlJbtBat91pphIjFw289t9DVh4N7Jva9EKnWnpJ\n",
228 "G0RqBXcjCa08YCqy/PJE4L8A33b9HQPPeTNR/0bgvujzGchoywPSq5U+nd6R7fp7IDfRjYDrEE99\n",
229 "DeyHrPb5lO364xI36zTb2q4/AUnt/SSyLHQHMvJZklQOIhYChyCLid2FWBoGIQrDfwGnAP8Gskzd\n",
230 "VvSbBgPvIMdpJjLHuxdikXgg1ewa4Jbo84+BHRAFI/3gT9/QQZa+/iIy9zwccVQrSeA5nbbrX4s8\n",
231 "cI6htIIQK7xdFJLIAvEEYjmYBlyP/E4LeXj92Xb94YHnnFtOjhrYJ3q/vtbpE9v1fwqcjYxUL0GO\n",
232 "51bI//g1YIzt+mNTSgJIivfNEIXgBOThfx0ySv8Nct7vgzgfj0+1HQf8E5iPKM/vI+vLHA9cZbs+\n",
233 "JZSEevgDBZ++3yIKzgVI1FeSrCnD6ci0zebAJxCfjmoZjxzXPPBL5By0gW8jCt3sqHwtkYL1N0RB\n",
234 "/R2ymOG2yHE5CLFAHAu8ahQEQxbfyijrDdML3HTTkWvUBRfsb88bPb6TzjEK+oHKL184YHL+Jmdl\n",
235 "u+XrJsYBhwaec0dcYLu+hzw0dkcu/AvjbUmLgu36DqIgPB54zuQq9nURMgI8LjnyBibZrj8z2s/l\n",
236 "tuvvVcJJbWvkXDoi8JzbKu0s8JxFtut/IqXgAPzOdv0/IiPnb5KhICAjpMGIEjAhPV1iu35HWsbA\n",
237 "c25ObD8ZURAeqibENBqpTYnark8FBSHiakRBOMx2/cHpB29kSv4KooSlLRYnIcrBHcBXk7/Fdv0b\n",
238 "gReAM23Xvz7wnJlVyFIJK3qfXUsj2/U/jiiiq4B9ktEytuv/Fhlpfx2xEnw31XxHYLfAc6bbrv8k\n",
239 "cny/Bnwz8Jy/2q6/DTLd9F8Zu94ceXAeEHhOvM7MNbbrT0UU4vNs15+c2FY3gedcm/hNP0EUhDvL\n",
240 "KMrJtkuIFPboWNWiIOSAO4HDE7/Dj67FSxEn21+m2pyOWDpuCDxn7fG2Xf8e4F1EIVsceE5oohgM\n",
241 "XVBKjURuSEke11qXMhv3OPR553VO9Sb407yJZwTexO8FnnNV/qYj11XlAOCfSeUA1s4D/y36mp7f\n",
242 "rAvb9fdGLDMzU8pBzMXIg2wsMhLKQiFhgxWVg5gM5SDm+uh9VHqD7fr7IlaNFcAJWb4UPcHLPvCc\n",
243 "2YgVZn3gyIwq30AsQg8lQ+aiefUfR1/PzlB08sD9Udusfmsi2t+Q6GutjspnIE6L16dDaSN/irMR\n",
244 "p8dTbddPOxK/nwgxTZr8747e30SsEkNL7PvXGQrAVYgvwggK/gK9mXMyfuON0fvWkY9Dkp2i97uT\n",
245 "hYHnLKNgURsDxknRUMz5FJ8XP22DHIbqSc9pxsSOW8ObtJ89ovdXbNcvpQC8j4zcdiTbnAoy4q2b\n",
246 "6Ia3CYV5/Y0zqsXOf4/WEYveaq5GQuOOQaZekhydqJNkW2BLZF2UzhL/R+xE2XAIa+A52nb9lUho\n",
247 "Y63hd7GD5d1ZGwPPmW27/iuIUrkLXc/n9xP13rZd/yNgVezoF8n1NjAyyyKETGGl97fGdv1/IlaL\n",
248 "3h7e+06WM2PgOQtt11+GTMcNo6vVJ1aWsyK+4nvFQjAKgiGBUmoshfnOmGe11vdl1Tf0GOaUKI9v\n",
249 "lqrE9lqJb6b/Hb3KsU2Zba/VslPb9bdDfA0ORLz0N62iWWxVqMkc3iZuRuawP2u7/g6JKI9RSCTR\n",
250 "YoodhOP/YgNKK2Ix2zZJzjnINMN2NbaL/4uiaIUE/0EUhB3pqiCkMwl2IscjXZZFJ/B2iW1xRtWR\n",
251 "ZWTqDcwps63U9f8Q0TSN7fp/iK0PtuvviPjmrCHyR1qrICilNkTmHjZDLsDke/JzOtwnzY1KqXcR\n",
252 "R4cFiBab9XlRT87I19dQSo1GNPz0tJOxHvR8mhrOVobB0XuAOBiWo1zmwaqdXW3X3x+4BzGVv4SM\n",
253 "pN9AnPEg21McxMIArTs2dRN4zoe26/8NOA6xGJwfbYqV9b8GnrM81Sz+Lz5A0qOXo2y4Ww3MoT4F\n",
254 "IY4+KTfNF58TaXN4VthstVNDitLKcdxvOjKmEj0tv0M953fs87E3Eul0B2JliBflOzfwnFcA+iul\n",
255 "5iEmwQFNEBaK569L0amUWggcqrXO8gg2FKHG2CdW4Uem9XvBlUflu7RUaiByU3lPa92ZKN8cSav8\n",
256 "fUQBTHKr1rrqueIsxp18/eg1azrLjSYB6NfRsY3G6Is9nDjDYxh4zundvbMotvtm5N50duA5P09t\n",
257 "T0faJIkfirU+zNrF1YiC4FBQECZE73/JqB//F+u14r+ImIVEOB1iu/6ZNfhwzEamp7YuU2e7RN1m\n",
258 "oZBnW5YVIfZ1qNWfotw51yuIph++hET0bAkcikwpTAEuCjxnSly3PzIP0a8NcnYgD6SBlSoaIhQX\n",
259 "V2UtVup24LBU6S7IyG+NUuodZP52awojrTSvIjeshlij9XdQKh2jXYRRDtpGfOCruQfEpmzbdn0V\n",
260 "dP9iPLsgjnEryI67Lzd/PCt6/5Tt+v3LJXAqQ/z7ut2ZO/Ccx23XfxUYZbt+7D8xCngl8Jwsa80s\n",
261 "ZBS8ke36O7cg4ybA5UgegJ0QE/XN5auvZRaiIMQRF12wXX8TCv9ls6eERpOtIMR+EXNS5YsRh8dS\n",
262 "To/V+CzUck21i6uR5++4wHNeKFXJRDH0PfoR5fqmtHKwDDhCa73O5JA3lCSeF04v6Z3FPRTMzBO7\n",
263 "S6AE8Q12PbomgYn5Xpm29yMPhu2RUK96iKMn9q6zfa38JXo/NHoly7oQeM5K4Iro60+jKINuJVJC\n",
264 "Yu/439uuX805A4VkWyfbrp+V/MdFnOmeCmpfFKsSRYMc2/U/DeyG3OfSjpOx5WmfVHmcuXFcFfus\n",
265 "5ZpqObbrb45EtswqpxyAcVI0FDMbOFxrXeT9a+heopvnEArzolvashT0wmbEapdgGpIU5XDb9R9F\n",
266 "YqrXQyyL8wPPeTeuGHjOMtv1T0VuqldH6W//jigNmyHOcAcBgwPPcZog20xkRLcJ8DPb9S9CRqM7\n",
267 "I7kDvoDE1hfdxwLPWWy7/plI7oCLbNffHXm4zUQeRtsjGRP/EXhOKSfcABkpj49i5+9G/putgHmB\n",
268 "5yxIN4iSF21C14V6Rtiu/yYSW15uHv4a4P8oKAedlPcvOAv4KmItfCTKKfAS8v8NR1ILHwnsl5GA\n",
269 "qF7ORdYaGA48HGWyfBqYgViDRwCfQR72PkDgOU9E2TvHI4m0TgeeRczb30DyH2iKcyA0ymrgWNv1\n",
270 "FyDK1NvIQ3tStN3LCH+9HUl29UPb9echFo8BUbtLEKfJtJ9EmgA59ifbrj8bCR3cGDlvZqdTLcPa\n",
271 "9NCbUMhs2GFLKvPFSAKxZl7/CxEL8pgoA+QMxD+kE3HenAHcHnjOGmNB6Dt8iGjHWSFKK4HHkcQr\n",
272 "OxvloLXYrr+77fqrEIejNyiE6P0WccZbabv+lFLtG+Ry5AY/BHkYfRDtR9M79QAAA3FJREFUcwYS\n",
273 "NdCFwHPuQR6a7wHfAR5GMhk+i9xcT6G6KIOKBJ6zFBn9r0GUmBlIWN9ziHf/5yjO/phsfy2yqt4i\n",
274 "xOJxF3INTI9k/Q7ZoV4xv0PC5LZCci4sQm6g08kYHdquvxy5lt4DwsSmF5EENCts1//Idv3M9LbR\n",
275 "egJTkEx4NvBA1joFifqLIjkeR6wcfwdeQfIFTEEcjHNU79RXkShvw95Ixs5+yOj/KuSh+ATiAHcq\n",
276 "xb4fxwOXRfJMQc6zlxGF6B3g4MBznmmWnBFzEUfP0xDFcCGiAG+JHKushESXIdanjRBF4l3EInAj\n",
277 "8vuOqWK/5yNRGaOQFNkfIhkOX6CQgwAA2/W3jkI3V0T7ejjatAFyXb2PXP/LbVnroWGi6bbzo697\n",
278 "IlaWk5Br93wkk+jztusP7o94Lna7eaoMZU0cVXIAped7eqGZfP2ZqmPFl+ptrVf3n19UpvVMYLRS\n",
279 "agBywxuEjLwWAe9qrTMXV2mUzs7OP/Xrp+6qt33Hmn5Zue3XNeZTOVoky5nqKiQkrNT883Qk3WvJ\n",
280 "sMLAc1bbrv9Z5AH6KWRkOB+5wRWlWo7a3Ga7/mOIomAho/GFyI30YeDREru7ELlOq07TG3jONbbr\n",
281 "T0Nu9KOQm+i/gFsDz3nTdv2fI2FbpdpfHnlpH4LcnHdAlIz5yLErqXgFnvOR7fo28lDYE7lu3kKO\n",
282 "TdZ9K52xrhTl7knnUVB6SqVeTsr4apQU6lDEbG4hCsFbROsRBE1ebjrwnNB2/XGIGf5gRBkYhPyv\n",
283 "7yDpjR9MtVkOnGK7/vWIgrFrVPcF4O8ZKbaXIuduWkH6KfL/JbkEsWClfWK2CDzHt10/jzhXjkGO\n",
284 "yzNIZEiRD00ga3ocaLv+kUh2xo8hSuVURKmIUyiXVGYCWVzKQlJD7xrJNg85b9LX8RLgF6X6SpFU\n",
285 "9Cpe28gaJgORqEEAbNffDLlvHIQoAndR8NEYilwjExD/nwuUiTQ0GAwGw7qC7fqjEUvKqsBzmhWd\n",
286 "t05gu/5pyNoifw48J9N5PForxQeeNFMMBoPBYDD0DWL/llvK1In9jt4zCoLBYDAYDH2DePo5MwrJ\n",
287 "dv0hFPwTnjBRDAaDwWAw9A3+hPgOHRPl25iK+FhsiuR4OARx0Lwf+J1REAwGg8Fg6AMEnvNklL78\n",
288 "HMRRca/E5hVINNIVwI2B56z6/3ExLRI31pXNAAAAAElFTkSuQmCC\n"
289 ],
290 "text/plain": [
291 "<IPython.core.display.Image at 0x111275490>"
292 ]
293 },
294 "execution_count": 6,
295 "metadata": {},
296 "output_type": "execute_result"
297 }
298 ],
299 "source": [
300 "from IPython.display import Image\n",
301 "Image(\"http://ipython.org/_static/IPy_header.png\")"
302 ]
303 }
304 ],
305 "metadata": {},
306 "nbformat": 4,
307 "nbformat_minor": 0
308 } No newline at end of file
@@ -0,0 +1,314 b''
1 {
2 "extra": "future",
3 "cells": [
4 {
5 "cell_type": "markdown",
6 "extra": 5,
7 "metadata": {},
8 "source": [
9 "# nbconvert latex test"
10 ]
11 },
12 {
13 "cell_type": "markdown",
14 "metadata": {},
15 "source": [
16 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
17 ]
18 },
19 {
20 "cell_type": "markdown",
21 "metadata": {},
22 "source": [
23 "## Printed Using Python"
24 ]
25 },
26 {
27 "cell_type": "code",
28 "execution_count": 1,
29 "future": "yes",
30 "metadata": {
31 "collapsed": false
32 },
33 "outputs": [
34 {
35 "name": "stdout",
36 "extra": "future",
37 "output_type": "stream",
38 "text": [
39 "hello\n"
40 ]
41 }
42 ],
43 "source": [
44 "print(\"hello\")"
45 ]
46 },
47 {
48 "cell_type": "markdown",
49 "metadata": {},
50 "source": [
51 "## Pyout"
52 ]
53 },
54 {
55 "cell_type": "code",
56 "execution_count": 3,
57 "metadata": {
58 "collapsed": false
59 },
60 "outputs": [
61 {
62 "data": {
63 "text/html": [
64 "\n",
65 "<script>\n",
66 "console.log(\"hello\");\n",
67 "</script>\n",
68 "<b>HTML</b>\n"
69 ],
70 "text/plain": [
71 "<IPython.core.display.HTML at 0x1112757d0>"
72 ]
73 },
74 "execution_count": 3,
75 "metadata": {},
76 "output_type": "execute_result"
77 }
78 ],
79 "source": [
80 "from IPython.display import HTML\n",
81 "HTML(\"\"\"\n",
82 "<script>\n",
83 "console.log(\"hello\");\n",
84 "</script>\n",
85 "<b>HTML</b>\n",
86 "\"\"\")"
87 ]
88 },
89 {
90 "cell_type": "code",
91 "execution_count": 7,
92 "metadata": {
93 "collapsed": false
94 },
95 "outputs": [
96 {
97 "data": {
98 "application/javascript": [
99 "console.log(\"hi\");"
100 ],
101 "text/plain": [
102 "<IPython.core.display.Javascript at 0x1112b4b50>"
103 ]
104 },
105 "metadata": {},
106 "output_type": "display_data"
107 }
108 ],
109 "source": [
110 "%%javascript\n",
111 "console.log(\"hi\");"
112 ]
113 },
114 {
115 "cell_type": "markdown",
116 "metadata": {},
117 "source": [
118 "### Image"
119 ]
120 },
121 {
122 "cell_type": "code",
123 "execution_count": 6,
124 "metadata": {
125 "collapsed": false
126 },
127 "outputs": [
128 {
129 "data": {
130 "image/png": [
131 "iVBORw0KGgoAAAANSUhEUgAAAggAAABDCAYAAAD5/P3lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
132 "AAAH3AAAB9wBYvxo6AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURB\n",
133 "VHic7Z15uBxF1bjfugkJhCWBsCSAJGACNg4QCI3RT1lEAVE+UEBNOmwCDcjHT1wQgU+WD3dFxA1o\n",
134 "CAikAZFFVlnCjizpsCUjHQjBIAkQlpCFJGS79fvjdGf69vTsc2fuza33eeaZmeqq6jM9vZw6dc4p\n",
135 "BUwC+tE+fqW1fqmRDpRSHjCggS40sBxYDCxKvL8KzNBaL21EPoPB0DPIWVY/4NlE0ffzYfhgu+Qx\n",
136 "GHoy/YFjaK+CcB3QkIIAHAWs3wRZsuhUSs0CXgQeBm7UWi/spn0Z+jA5yxpEfYruqnwYllRic5a1\n",
137 "MaWv8U5gaT4M19Sx396IAnZLfB/SLkEMhp5O/3YL0AvoAHaKXl8HLlZK3QZcpbWe0lbJDOsaHuDU\n",
138 "0e4u4JAy2wPk/C1JzrKWArOQ0fUtwH35MOysQxaDwbCO0NFuAXoh6wPjgQeUUvcqpUa0WyCDoQls\n",
139 "CIwBjgfuAV7KWdY+7RWpmJxlXZezrEdylvXxdstiMKzrGAtCYxwI/EspdZbW+g/tFsbQ67kQuBHY\n",
140 "FNgseh9FV6vCbUAeWBC9PgBeq2EfS6J2MQOBrRDTe5KdgAdzlvW1fBjeUUP/3UbOsoYBE6OvG7VT\n",
141 "FoOhL9Af+BUwFLkZpV+DaY6V4UPkRpb1+ncT+m8nGwK/V0oN01qf025hDL2XfBi+DLycLMtZVo6u\n",
142 "CsKfGnSq8/NheEpqHwOBEcDBwJnAsGhTP2ByzrJG5cPwnQb22Sy+0G4BDIa+RH+t9dmlNiqlFKIk\n",
143 "JJWGi+jq5JPmq8BbJJQArfXqpkncczlbKbVQa/3rdgtiMNRCPgxXAK8Ar+Qs63LgXmDvaPPGwPeA\n",
144 "H7VJvCRfbLcABkNfouwUg9ZaAwuj178BlFLvVejzgR4WFviM1npcuQpKqf6IyXIjxLS7GzAWuUnu\n",
145 "XsO+fqWUellr3ZBJdq/jr9+BDn1uve07O9Rz0y6f8PtGZGgWe53oT6SBkZ/q1/nHZy47aloTRTKU\n",
146 "IR+Gy3OWNR6Zxtg0Kv4KRkEwGPocxgcBiCwcsSI0F5iOhF+ilPok8C3gVGS+thK/VErdrbWuO2ys\n",
147 "s/+aLZTuOKbe9krrIUCPUBB0B+PQ1P1bdKe6EzAKQgvJh+GbOct6gkJkxM45y+qXDIWMHBhjBWJe\n",
148 "PgyDWvaRs6zPIVObAG/nw/DpEvUGAp8E9gGGJzbtl7Os7cvs4skqp0V0Yl8jgcOBjyMDhbmIZeWl\n",
149 "fBg+UUVfReQsayhwELAnsAXi6/E28BxwTz4MP6iyn92RaSCA+/NhuCwqXx9R4MYhU0MfRTK/AjyW\n",
150 "D8MFGd0ZDFVhFIQKaK3/BXxfKXUlklTq0xWafAI4Driyu2UzGLqRlygoCArYHJif2H4gcFb0+Z2c\n",
151 "ZW2bD8NV1XScs6yNgH8g/jsAPwCeTmzfFPgjYsnbiez71MUVdnMQcF8V4nyUs6whwB8QX4+0s2Ys\n",
152 "0yPAt/NhGFbRZ/wbzgO+DaxXotqqnGX9GbigCkXhf5CBCsDngYdzljURGQhsWqLN+znL+iFwdT4M\n",
153 "dYk6BkNJTJhjlWitQ2Bf4P4qqv848t8wGHor6Yd9+ruHJFkC2BI4rIa+D6egHKwmstYlGAxMQCwH\n",
154 "rRjEPI5ER5S7ZvcFXsxZ1phKneUsawSi8HyH0soB0bbvAM9Ebaplt5xlnYkct1LKAYiFZhJwSQ19\n",
155 "GwxrMRaEGtBar1RKfRX4JxIzXortou3PN1mE+YgJsSwaeoLHOQCqUy3QSr9eqZ6G/gq2aYVMhqrY\n",
156 "OfF5FeJwvJZ8GM7JWdY/gC9HRS7wtyr7Pjrx+e6MqYC3KLbU7Qhck/h+FJIKvRRVjfSREXicU8EH\n",
157 "pgAvIIqLBZwGfC7avl5Uf29KkLOsTZCMq8npj9sQx89no37HIlaAODplNPBIzrJ2z4dhNVlaT0HC\n",
158 "XwFmIkrAC4if2PaIz8/3KCgn385Z1pX5MJxeRd8Gw1qMglAjWutlSqnTgUcqVP0SzVYQtP5mcMXE\n",
159 "SvvtUUy9YsK5QEWHy7EnTB6lOtSsFohkqEDOsgYAdqJoagkT9Z8pKAj75yzr4/kwnF2h748ho/GY\n",
160 "q9J1oqiKLj4JOctKK8Yz8mH4Yrl9VcnHkXVYTsyHoZ8WJWdZNyPThbF5/3M5yzowH4alpi9+T0E5\n",
161 "WA18Nx+Gf0zVeRG4KmdZ90R9bwCMRKwyX69C5h2j91uA4/JhuCSxbTYwJWdZtwNPIFbifsAFSISZ\n",
162 "wVA1ZoqhDrTWjyIjjXIc3ApZDIZu4ELgY4nvt5Wody8wJ/qsgBOr6HsihfvOfCRrY7v5dYZyAECk\n",
163 "GP0ISEZmZYZ55yxrB8SyEXNxhnKQ7Pt64H8TRUfmLGuXKmWeC4xPKQfJvp9CLCJlZTYYymEUhPq5\n",
164 "tcL2XVsihcHQJHKWtU3Osi5GnAZj5iKWgiKitRouTxQdl7OscnPu0HV64dp8GLY7R8pyxEGxJPkw\n",
165 "fBcZ9ceUSvN8IoV76upK/UZcgawcG3NKqYopfleFU+gDic/b5SzLWIwNNWFOmPqp5CG9sVJqPa11\n",
166 "VZ7dBkOL2D1nWcmcBkOR8MFtgM/QdTXJZcCR+TBcXqa/SYj5egAFZ8VMX4ScZe2FRPnEXF2z9M3n\n",
167 "3nwYVsrtAmK6/0z0uVR4ZXLtivvzYfhGpU7zYbgkZ1k3ACdHRQdWIQsUO3ZmkUzB3Q/xjaolLbeh\n",
168 "j2MUhDrRWr+mlFpJ+eV5hyIxz4YWs98Fj/Rf8uZbozo0/ZYt7D8rf9ORK9stUw/hU9GrEnMAp1R+\n",
169 "gph8GL4bzdNPiIpOorSzYtJ68FS1IYPdTLWp3hcnPm+Q3pizrA7E+TCmFn+aZN0dcpY1LB+G5e4b\n",
170 "y6rM8bA49X39GmQyGMwUQ4NUGnkMrbDd0A3sdeLk4z6cN+89pTtDTWd+gyErF+7pTv5eu+XqJbyK\n",
171 "TDHsmg/DJ6tsc2ni8+dzljUqXSGaevhmoqjIObFNVBzlV8kQug4W5tbQNl13WGatAv+poW+DoW6M\n",
172 "BaExPgC2LrO9nHWhpSilDqI4NPMhrfXUJvS9M/DfqeJXtdY3N9p3rex50uQ9lFKT6BrTvoFCXbTX\n",
173 "yZNfmnrZxHtbLVMP4xng74nvK5DzeD7wfIWRayb5MHwiZ1kzgF0oOCuemar2ZQoK8zLgr7Xup5t4\n",
174 "s0n9DEl9b0RBSPeV5q0a+jYY6sYoCI1RacnZ91siRXUMAH6eKnsYicdulDOAY1NlpzWh35pRqG9R\n",
175 "IuGN7uw4AfG878s8nw/DX3RDv5dScGY8NmdZP86HYXJaJzm9cHMp7/s2UHdK9BTpKaxBNbRN163k\n",
176 "t9Rux05DH8FMMTTGZhW2v9sSKarjbopNk/sqpUY30qlSahCSGS/JCuD6RvqtF6UpMm/HaHTJbYaG\n",
177 "mQzED/0umRVzlrUZhXwJ0HOmF5pJOlXyxzJrZbNt6rtZP8HQIzAKQp0opTZAlsItxTKtdTnv75YS\n",
178 "LR7lpYqrjV0vx2EUH4fbtdZtucnpMqOrDjPy6jYii8DkRFHSYnAEhem22cBjrZKrVeTDcCldTf/p\n",
179 "h345ksrEGprnF2EwNIRREOrnMxW2z2uJFLVxJcXmy2OVUo34ShydUda+EaIq7T2u0SZTY/eSdFY8\n",
180 "MGdZm0efk86J6/LCQUnFp5pIkZjkcvQz8mH4YZPkMRgawigI9VNp7v7BlkhRA1rr+RQneNqC2hba\n",
181 "WYtSajiS9z3JXLomaGktq/VllLIUdKqSWe0MjZMPwxlIel8Q/6Zv5CxrGIX8AJ10XU+hFtIRQ+UW\n",
182 "KWoXyYyTu+Qsa79KDXKWNRpJyx5zZ9OlMhjqxCgIdaCU6g98o0K1npBCNotLM8rcOvuagCRgSXKN\n",
183 "1rozq3IrCCZNfFkrfRjotWsCaJinUBODK51/tkuuPkTy/DoYOIDCfeb+fBjW4t2/lqhdcmRdbUri\n",
184 "VnILXS2HZ1WRvfAcCk61K4A/dYdgBkM9GAWhPr5F6XSrIBf6Qy2SpSaidSReShV/XilV7veUIj29\n",
185 "oOkB2fGmXT7x7sCbOGpFf7VZx4A1m0/znG2nehMyc+0bms7NFJxzxwH7J7Y1OvWUPG9/mLOsLRvs\n",
186 "r6lEaaOT0TtfBB5ITLWsJWdZg3KWdRNwTKL4wnwYzu9mMQ2GqjFhjjWilBqBpJYtx51a66UV6rST\n",
187 "S+maJz52VvxRdvVilFK7UbzexGNa67Kr+bWS6X+ekPYs79HkLGt34JOI+Xyz6D2d1vfMnGUdini6\n",
188 "L0C851/Oh2HD+SyaQT4MV+YsaxJyLm1Gwf9gAXBHg93/JNHHtsArOcuajCztPBDYCkkytBXg5sOw\n",
189 "5QmF8mF4W86yLgK+HxXtC8zKWVaALMm8CslHsicS7RFzL8VhyAZDWzEKQg0opbYE7qd8prPVdF2h\n",
190 "rSdyLfALYMNE2XFKqR/XsHbEURll62L4Wiv5PuBUqPPF6JXkLuCQbpGoPi4HfohYKGMHWD9axrlu\n",
191 "8mF4Z7RuwfioaDBwaonqRemQW0U+DH+Qs6xFwHnIFNwQsv+3mMnA8dHiVwZDj8FMMVSJUuow4DkK\n",
192 "a7GX4gqt9cstEKlutNaL6boULMho5tBq2iul+lH8IFuCmJcNfZx8GM6hOCFVU5THfBhOQHxfylkH\n",
193 "3gY+asb+6iUfhhcCewC3l5BlFbJk/P75MDwqlVTKYOgRKK1rizhSSk2h67ximo1abV5XSi2n9EIk\n",
194 "z2itx5XYVqnfQcjI7DiqW2XtfeCTUbRA3ex50nWfUrqjeJEcrfcLrpj4SCN9xyilxgDPp4of0Fof\n",
195 "UEXbg4B/pIqv1FrXnVNh7AmTR3V0qIwwRH1E4E28pd5+De0hZ1m/Bb4bfX0+H4Z7dMM+hgGjkDwC\n",
196 "S5FpjFk9bR4/Z1mDkGmF4VHR20g4Y3oxJYOhR9EXphg6lFLlVjFbH0mZvDGwCTAayCFe0ntTOZ1y\n",
197 "zDLgkEaVg1ahtX5BKfUU8OlE8ReUUjtorSstCduzch8YehSR5/6ERFG3nBvRuhE9frXUfBguA6pd\n",
198 "+Mpg6DH0BQXBBro7o+Ea4Bta66e6eT/N5lK6KggKOAE4u1QDpdTGFOdNmNkLf7uh+zgYcRQEMa+3\n",
199 "Je22wWBoDOOD0DhLgYla67vaLUgd3ETxglLHRXkeSnEExQ5gbQ9tNPQokis5TsqHoVlbwGDohRgF\n",
200 "oTECYHet9Y3tFqQetNYrKDb/DqN46eYk6emF1UhUhMFAzrImUEhDvgr4VRvFMRgMDWAUhPpYAvwf\n",
201 "8Bmte31+/8uQBEdJMjMrKqW2o5A2N+YfWusePw9s6F5yltWRs6zxwKRE8RXtyEVgMBiaQ1/wQWgm\n",
202 "eWTe/jqtdU9Zz74htNavKaXuAw5KFB+glBqptZ6Tqj6RQlrYGDO90AfJWdY5wNeQFQwHIAmetk5U\n",
203 "eZFCsiCDwdALMQpCed5AphEC4NF12BHvUroqCAoJ7TwvVS+d++BdJEmPoe+xKRLnn0UeODwfhm3N\n",
204 "RWAwGBqjLygIbwN/LbNdI1MGH6ReL/eWkMUmcDeSeGa7RNlRSqnzdZQoQym1C7Bzqt11NWReNKxb\n",
205 "zEMU6GHAesBiYCaSLOviaF0Cg8HQi+kLCsLrWuvT2y1ET0ZrvUYp5SG57mO2Bz4LPB59/2ZRQ5P7\n",
206 "oM+SD8OLgYvbLYfBYOg+jJOiIeZKxOs8STJiIb28daC1/lf3imQwGAyGdmEUBAMA0XTKraniI5VS\n",
207 "A6O0zOnloI31wGAwGNZhjIJgSHJp6vtgJBNlehW65cANLZHIYDAYDG3BKAiGtWitHwVeShV/muLF\n",
208 "uW7VWi9qjVQGg8FgaAd9wUnRUBuXAn9IfN8f+FyqTo/OfbDnSX8brDpXnqEUe2ropzQvdtDx66ev\n",
209 "GN9XolIMPQDb9T8LrBd4zsPtlsXQe7Bd/0BgQeA5QbtlMQqCIc21wC+ADaPv6WWu5wAPtVKgWtjt\n",
210 "6Os2XG/9jhdQjIzTQ2rFF9bQecy4E2/I9UQlwXb9LYDDK1R7K/Cc21shj6FxbNcfDjwGKNv1Rwae\n",
211 "83q7ZWo2tusPBb6ELGW9BbAICX99Gngs8Jx0hlZDBWzXHwvcC6ywXX9o4DlL2ymPURAMXdBaL1ZK\n",
212 "+ZRItwz8Jc6N0BMZMFB9GxiZsWnzTjrPAH7QWomqYgTF/h9pngC6RUGwXf+XwC2B50ztjv57M7br\n",
213 "XwJMCjxneo1NP0SWgAfJq7LOYLv+esAFwOkUL9wWM912/d0Dz+lsnWQ9A9v1BwEXAT8PPKfWVOML\n",
214 "kPVt3kNWQm0rxgfBkEWph5UG/tJCOWqnQ40ttUkrvWcrRamWwHOmAZsguSfGAi9Hmy5AUhgPAz7f\n",
215 "Hfu2XX8k8ENgx+7ovzdju/4uwP9D/peaCDxnCbANsF3gOYubLVu7sF1/AHAHcBaiHDwI/C+ywNsE\n",
216 "4KfA68BdfVE5iNgbOBmxqtRE4Dn/BoYDnwg8Z02zBasVY0EwFKG1fkEp9RTioJjkIa11zzaVarYq\n",
217 "vVFt2TpBaiN6oCwB5tiu/2FUPCvwnLTTaLM5oJv77800dGwCz1kXHXkvRNKydwI/Cjzn1+kKtuuf\n",
218 "i2TX7Ks0et681yxBGsUoCIZSBBQrCL0h98EbdW7rddiuPwoYFJu/bdffFNgL2BZ4DZgWKR5ZbRWS\n",
219 "2+KIqGiE7fpjUtXmlrtZRdaHscBAYDowM/CckimWbdffFfgw8JzXou/9kfUccojV5MXAcz4s0XYw\n",
220 "sCsymu8PzAVmBJ7zVqn9pdoPRVKF7wSsAN4EgqzRve36HcAoZDEqgO0zjs3rged8kGo3gOJ05ADT\n",
221 "s0bTkan+k9HXGaVGjNFxykVf81nH2Hb9Ich/MRJJeT291H9fL7brj6CwANfPspQDgOi3rijRx/rI\n",
222 "b8kB7wPPBZ4zL6Ne/JvfCDzn/WhufhvgvsBzVkR1dgN2AR4JPGduom38P7wXeM7c6FzfCfgU4iMR\n",
223 "lFLebNfPIefXzMBzikz8tusPQyx676bljmTeCfhyVLST7frp//TV9Dluu/6GwOhUvTWB58zIkjFq\n",
224 "sykyNfmfwHMW2K7fLzoWeyDTFPnAc14t1T7qYwNgT+Rc/wi5ZyT/N20UBEMRSqn+wNdTxQspTqTU\n",
225 "41BaP6yVOipzGzzSYnG6m6uBz0YPv7OQm3dytc35tuuflHZutF3/BuArwEaJ4p/QNdU2wGnAH9M7\n",
226 "jRSTG5CbS5LQdv2joymTLKYBzwHjbNc/DomW2TCxfbXt+sMCz3k/sa8RwM+Qh/X6qf5W2q4/CTit\n",
227 "zMN1OPB7CopQktW2658YeM5fEvXvRKZzBiXqZaWUPha4JlW2NfB8Rt0hiANfmjWIuf5jiLPfvVm/\n",
228 "AfmvbgNmB54zKrkheuD+Bjg11Wap7fpnBJ5TybelFk4E+iE+Fb+ptbHt+scg//nGqfJbgeMDz1mY\n",
229 "KN4UOZYX2q7fSWHhuNdt198ZOBc4MypbbLv+5wPPeTb6PiJqe5ft+ichx3WXRN8rbdc/OfCcrGis\n",
230 "R4ChiHKSlSn2f4BzkOvitMRvCKJ9DEzU9TPafwGZlkkyBvExSrKUrtdnmoOBycA5tus/iCyat3li\n",
231 "u7Zd/0rk2ihS1mzXPwT4E3LulaLTKAiGLL6EaMlJbtBat91pphIjFw289t9DVh4N7Jva9EKnWnpJ\n",
232 "G0RqBXcjCa08YCqy/PJE4L8A33b9HQPPeTNR/0bgvujzGchoywPSq5U+nd6R7fp7IDfRjYDrEE99\n",
233 "DeyHrPb5lO364xI36zTb2q4/AUnt/SSyLHQHMvJZklQOIhYChyCLid2FWBoGIQrDfwGnAP8Gskzd\n",
234 "VvSbBgPvIMdpJjLHuxdikXgg1ewa4Jbo84+BHRAFI/3gT9/QQZa+/iIy9zwccVQrSeA5nbbrX4s8\n",
235 "cI6htIIQK7xdFJLIAvEEYjmYBlyP/E4LeXj92Xb94YHnnFtOjhrYJ3q/vtbpE9v1fwqcjYxUL0GO\n",
236 "51bI//g1YIzt+mNTSgJIivfNEIXgBOThfx0ySv8Nct7vgzgfj0+1HQf8E5iPKM/vI+vLHA9cZbs+\n",
237 "JZSEevgDBZ++3yIKzgVI1FeSrCnD6ci0zebAJxCfjmoZjxzXPPBL5By0gW8jCt3sqHwtkYL1N0RB\n",
238 "/R2ymOG2yHE5CLFAHAu8ahQEQxbfyijrDdML3HTTkWvUBRfsb88bPb6TzjEK+oHKL184YHL+Jmdl\n",
239 "u+XrJsYBhwaec0dcYLu+hzw0dkcu/AvjbUmLgu36DqIgPB54zuQq9nURMgI8LjnyBibZrj8z2s/l\n",
240 "tuvvVcJJbWvkXDoi8JzbKu0s8JxFtut/IqXgAPzOdv0/IiPnb5KhICAjpMGIEjAhPV1iu35HWsbA\n",
241 "c25ObD8ZURAeqibENBqpTYnark8FBSHiakRBOMx2/cHpB29kSv4KooSlLRYnIcrBHcBXk7/Fdv0b\n",
242 "gReAM23Xvz7wnJlVyFIJK3qfXUsj2/U/jiiiq4B9ktEytuv/Fhlpfx2xEnw31XxHYLfAc6bbrv8k\n",
243 "cny/Bnwz8Jy/2q6/DTLd9F8Zu94ceXAeEHhOvM7MNbbrT0UU4vNs15+c2FY3gedcm/hNP0EUhDvL\n",
244 "KMrJtkuIFPboWNWiIOSAO4HDE7/Dj67FSxEn21+m2pyOWDpuCDxn7fG2Xf8e4F1EIVsceE5oohgM\n",
245 "XVBKjURuSEke11qXMhv3OPR553VO9Sb407yJZwTexO8FnnNV/qYj11XlAOCfSeUA1s4D/y36mp7f\n",
246 "rAvb9fdGLDMzU8pBzMXIg2wsMhLKQiFhgxWVg5gM5SDm+uh9VHqD7fr7IlaNFcAJWb4UPcHLPvCc\n",
247 "2YgVZn3gyIwq30AsQg8lQ+aiefUfR1/PzlB08sD9Udusfmsi2t+Q6GutjspnIE6L16dDaSN/irMR\n",
248 "p8dTbddPOxK/nwgxTZr8747e30SsEkNL7PvXGQrAVYgvwggK/gK9mXMyfuON0fvWkY9Dkp2i97uT\n",
249 "hYHnLKNgURsDxknRUMz5FJ8XP22DHIbqSc9pxsSOW8ObtJ89ovdXbNcvpQC8j4zcdiTbnAoy4q2b\n",
250 "6Ia3CYV5/Y0zqsXOf4/WEYveaq5GQuOOQaZekhydqJNkW2BLZF2UzhL/R+xE2XAIa+A52nb9lUho\n",
251 "Y63hd7GD5d1ZGwPPmW27/iuIUrkLXc/n9xP13rZd/yNgVezoF8n1NjAyyyKETGGl97fGdv1/IlaL\n",
252 "3h7e+06WM2PgOQtt11+GTMcNo6vVJ1aWsyK+4nvFQjAKgiGBUmoshfnOmGe11vdl1Tf0GOaUKI9v\n",
253 "lqrE9lqJb6b/Hb3KsU2Zba/VslPb9bdDfA0ORLz0N62iWWxVqMkc3iZuRuawP2u7/g6JKI9RSCTR\n",
254 "YoodhOP/YgNKK2Ix2zZJzjnINMN2NbaL/4uiaIUE/0EUhB3pqiCkMwl2IscjXZZFJ/B2iW1xRtWR\n",
255 "ZWTqDcwps63U9f8Q0TSN7fp/iK0PtuvviPjmrCHyR1qrICilNkTmHjZDLsDke/JzOtwnzY1KqXcR\n",
256 "R4cFiBab9XlRT87I19dQSo1GNPz0tJOxHvR8mhrOVobB0XuAOBiWo1zmwaqdXW3X3x+4BzGVv4SM\n",
257 "pN9AnPEg21McxMIArTs2dRN4zoe26/8NOA6xGJwfbYqV9b8GnrM81Sz+Lz5A0qOXo2y4Ww3MoT4F\n",
258 "IY4+KTfNF58TaXN4VthstVNDitLKcdxvOjKmEj0tv0M953fs87E3Eul0B2JliBflOzfwnFcA+iul\n",
259 "5iEmwQFNEBaK569L0amUWggcqrXO8gg2FKHG2CdW4Uem9XvBlUflu7RUaiByU3lPa92ZKN8cSav8\n",
260 "fUQBTHKr1rrqueIsxp18/eg1azrLjSYB6NfRsY3G6Is9nDjDYxh4zundvbMotvtm5N50duA5P09t\n",
261 "T0faJIkfirU+zNrF1YiC4FBQECZE73/JqB//F+u14r+ImIVEOB1iu/6ZNfhwzEamp7YuU2e7RN1m\n",
262 "oZBnW5YVIfZ1qNWfotw51yuIph++hET0bAkcikwpTAEuCjxnSly3PzIP0a8NcnYgD6SBlSoaIhQX\n",
263 "V2UtVup24LBU6S7IyG+NUuodZP52awojrTSvIjeshlij9XdQKh2jXYRRDtpGfOCruQfEpmzbdn0V\n",
264 "dP9iPLsgjnEryI67Lzd/PCt6/5Tt+v3LJXAqQ/z7ut2ZO/Ccx23XfxUYZbt+7D8xCngl8Jwsa80s\n",
265 "ZBS8ke36O7cg4ybA5UgegJ0QE/XN5auvZRaiIMQRF12wXX8TCv9ls6eERpOtIMR+EXNS5YsRh8dS\n",
266 "To/V+CzUck21i6uR5++4wHNeKFXJRDH0PfoR5fqmtHKwDDhCa73O5JA3lCSeF04v6Z3FPRTMzBO7\n",
267 "S6AE8Q12PbomgYn5Xpm29yMPhu2RUK96iKMn9q6zfa38JXo/NHoly7oQeM5K4Iro60+jKINuJVJC\n",
268 "Yu/439uuX805A4VkWyfbrp+V/MdFnOmeCmpfFKsSRYMc2/U/DeyG3OfSjpOx5WmfVHmcuXFcFfus\n",
269 "5ZpqObbrb45EtswqpxyAcVI0FDMbOFxrXeT9a+heopvnEArzolvashT0wmbEapdgGpIU5XDb9R9F\n",
270 "YqrXQyyL8wPPeTeuGHjOMtv1T0VuqldH6W//jigNmyHOcAcBgwPPcZog20xkRLcJ8DPb9S9CRqM7\n",
271 "I7kDvoDE1hfdxwLPWWy7/plI7oCLbNffHXm4zUQeRtsjGRP/EXhOKSfcABkpj49i5+9G/putgHmB\n",
272 "5yxIN4iSF21C14V6Rtiu/yYSW15uHv4a4P8oKAedlPcvOAv4KmItfCTKKfAS8v8NR1ILHwnsl5GA\n",
273 "qF7ORdYaGA48HGWyfBqYgViDRwCfQR72PkDgOU9E2TvHI4m0TgeeRczb30DyH2iKcyA0ymrgWNv1\n",
274 "FyDK1NvIQ3tStN3LCH+9HUl29UPb9echFo8BUbtLEKfJtJ9EmgA59ifbrj8bCR3cGDlvZqdTLcPa\n",
275 "9NCbUMhs2GFLKvPFSAKxZl7/CxEL8pgoA+QMxD+kE3HenAHcHnjOGmNB6Dt8iGjHWSFKK4HHkcQr\n",
276 "OxvloLXYrr+77fqrEIejNyiE6P0WccZbabv+lFLtG+Ry5AY/BHkYfRDtR9M79QAAA3FJREFUcwYS\n",
277 "NdCFwHPuQR6a7wHfAR5GMhk+i9xcT6G6KIOKBJ6zFBn9r0GUmBlIWN9ziHf/5yjO/phsfy2yqt4i\n",
278 "xOJxF3INTI9k/Q7ZoV4xv0PC5LZCci4sQm6g08kYHdquvxy5lt4DwsSmF5EENCts1//Idv3M9LbR\n",
279 "egJTkEx4NvBA1joFifqLIjkeR6wcfwdeQfIFTEEcjHNU79RXkShvw95Ixs5+yOj/KuSh+ATiAHcq\n",
280 "xb4fxwOXRfJMQc6zlxGF6B3g4MBznmmWnBFzEUfP0xDFcCGiAG+JHKushESXIdanjRBF4l3EInAj\n",
281 "8vuOqWK/5yNRGaOQFNkfIhkOX6CQgwAA2/W3jkI3V0T7ejjatAFyXb2PXP/LbVnroWGi6bbzo697\n",
282 "IlaWk5Br93wkk+jztusP7o94Lna7eaoMZU0cVXIAped7eqGZfP2ZqmPFl+ptrVf3n19UpvVMYLRS\n",
283 "agBywxuEjLwWAe9qrTMXV2mUzs7OP/Xrp+6qt33Hmn5Zue3XNeZTOVoky5nqKiQkrNT883Qk3WvJ\n",
284 "sMLAc1bbrv9Z5AH6KWRkOB+5wRWlWo7a3Ga7/mOIomAho/GFyI30YeDREru7ELlOq07TG3jONbbr\n",
285 "T0Nu9KOQm+i/gFsDz3nTdv2fI2FbpdpfHnlpH4LcnHdAlIz5yLErqXgFnvOR7fo28lDYE7lu3kKO\n",
286 "TdZ9K52xrhTl7knnUVB6SqVeTsr4apQU6lDEbG4hCsFbROsRBE1ebjrwnNB2/XGIGf5gRBkYhPyv\n",
287 "7yDpjR9MtVkOnGK7/vWIgrFrVPcF4O8ZKbaXIuduWkH6KfL/JbkEsWClfWK2CDzHt10/jzhXjkGO\n",
288 "yzNIZEiRD00ga3ocaLv+kUh2xo8hSuVURKmIUyiXVGYCWVzKQlJD7xrJNg85b9LX8RLgF6X6SpFU\n",
289 "9Cpe28gaJgORqEEAbNffDLlvHIQoAndR8NEYilwjExD/nwuUiTQ0GAwGw7qC7fqjEUvKqsBzmhWd\n",
290 "t05gu/5pyNoifw48J9N5PForxQeeNFMMBoPBYDD0DWL/llvK1In9jt4zCoLBYDAYDH2DePo5MwrJ\n",
291 "dv0hFPwTnjBRDAaDwWAw9A3+hPgOHRPl25iK+FhsiuR4OARx0Lwf+J1REAwGg8Fg6AMEnvNklL78\n",
292 "HMRRca/E5hVINNIVwI2B56z6/3ExLRI31pXNAAAAAElFTkSuQmCC\n"
293 ],
294 "extra": "yes",
295 "text/plain": [
296 "<IPython.core.display.Image at 0x111275490>"
297 ]
298 },
299 "execution_count": 6,
300 "metadata": {},
301 "extra": "yes",
302 "output_type": "execute_result"
303 }
304 ],
305 "source": [
306 "from IPython.display import Image\n",
307 "Image(\"http://ipython.org/_static/IPy_header.png\")"
308 ]
309 }
310 ],
311 "metadata": {},
312 "nbformat": 4,
313 "nbformat_minor": 99
314 } No newline at end of file
@@ -0,0 +1,19 b''
1 """The main API for the v4 notebook format."""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 from .nbbase import (
7 nbformat, nbformat_minor, nbformat_schema,
8 new_code_cell, new_markdown_cell, new_notebook,
9 new_output, output_from_msg,
10 )
11
12 from .nbjson import reads, writes, to_notebook
13 reads_json = reads
14 writes_json = writes
15 to_notebook_json = to_notebook
16
17 from .convert import downgrade, upgrade
18
19
@@ -0,0 +1,249 b''
1 """Code for converting notebooks to and from v3."""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 import json
7 import re
8
9 from .nbbase import (
10 nbformat, nbformat_minor,
11 NotebookNode,
12 )
13
14 from IPython.nbformat import v3
15 from IPython.utils.log import get_logger
16
17 def _warn_if_invalid(nb, version):
18 """Log validation errors, if there are any."""
19 from IPython.nbformat import validate, ValidationError
20 try:
21 validate(nb, version=version)
22 except ValidationError as e:
23 get_logger().error("Notebook JSON is not valid v%i: %s", version, e)
24
25 def upgrade(nb, from_version=3, from_minor=0):
26 """Convert a notebook to v4.
27
28 Parameters
29 ----------
30 nb : NotebookNode
31 The Python representation of the notebook to convert.
32 from_version : int
33 The original version of the notebook to convert.
34 from_minor : int
35 The original minor version of the notebook to convert (only relevant for v >= 3).
36 """
37 if from_version == 3:
38 # Validate the notebook before conversion
39 _warn_if_invalid(nb, from_version)
40
41 # Mark the original nbformat so consumers know it has been converted
42 orig_nbformat = nb.pop('orig_nbformat', None)
43 nb.metadata.orig_nbformat = orig_nbformat or 3
44
45 # Mark the new format
46 nb.nbformat = nbformat
47 nb.nbformat_minor = nbformat_minor
48
49 # remove worksheet(s)
50 nb['cells'] = cells = []
51 # In the unlikely event of multiple worksheets,
52 # they will be flattened
53 for ws in nb.pop('worksheets', []):
54 # upgrade each cell
55 for cell in ws['cells']:
56 cells.append(upgrade_cell(cell))
57 # upgrade metadata
58 nb.metadata.pop('name', '')
59 # Validate the converted notebook before returning it
60 _warn_if_invalid(nb, nbformat)
61 return nb
62 elif from_version == 4:
63 # nothing to do
64 if from_minor != nbformat_minor:
65 nb.metadata.orig_nbformat_minor = from_minor
66 nb.nbformat_minor = nbformat_minor
67
68 return nb
69 else:
70 raise ValueError('Cannot convert a notebook directly from v%s to v4. ' \
71 'Try using the IPython.nbformat.convert module.' % from_version)
72
73 def upgrade_cell(cell):
74 """upgrade a cell from v3 to v4
75
76 heading cell -> markdown heading
77 code cell:
78 - remove language metadata
79 - cell.input -> cell.source
80 - cell.prompt_number -> cell.execution_count
81 - update outputs
82 """
83 cell.setdefault('metadata', NotebookNode())
84 if cell.cell_type == 'code':
85 cell.pop('language', '')
86 if 'collapsed' in cell:
87 cell.metadata['collapsed'] = cell.pop('collapsed')
88 cell.source = cell.pop('input', '')
89 cell.execution_count = cell.pop('prompt_number', None)
90 cell.outputs = upgrade_outputs(cell.outputs)
91 elif cell.cell_type == 'heading':
92 cell.cell_type = 'markdown'
93 level = cell.pop('level', 1)
94 cell.source = '{hashes} {single_line}'.format(
95 hashes='#' * level,
96 single_line = ' '.join(cell.get('source', '').splitlines()),
97 )
98 elif cell.cell_type == 'html':
99 # Technically, this exists. It will never happen in practice.
100 cell.cell_type = 'markdown'
101 return cell
102
103 def downgrade_cell(cell):
104 """downgrade a cell from v4 to v3
105
106 code cell:
107 - set cell.language
108 - cell.input <- cell.source
109 - cell.prompt_number <- cell.execution_count
110 - update outputs
111 markdown cell:
112 - single-line heading -> heading cell
113 """
114 if cell.cell_type == 'code':
115 cell.language = 'python'
116 cell.input = cell.pop('source', '')
117 cell.prompt_number = cell.pop('execution_count', None)
118 cell.collapsed = cell.metadata.pop('collapsed', False)
119 cell.outputs = downgrade_outputs(cell.outputs)
120 elif cell.cell_type == 'markdown':
121 source = cell.get('source', '')
122 if '\n' not in source and source.startswith('#'):
123 prefix, text = re.match(r'(#+)\s*(.*)', source).groups()
124 cell.cell_type = 'heading'
125 cell.source = text
126 cell.level = len(prefix)
127 return cell
128
129 _mime_map = {
130 "text" : "text/plain",
131 "html" : "text/html",
132 "svg" : "image/svg+xml",
133 "png" : "image/png",
134 "jpeg" : "image/jpeg",
135 "latex" : "text/latex",
136 "json" : "application/json",
137 "javascript" : "application/javascript",
138 };
139
140 def to_mime_key(d):
141 """convert dict with v3 aliases to plain mime-type keys"""
142 for alias, mime in _mime_map.items():
143 if alias in d:
144 d[mime] = d.pop(alias)
145 return d
146
147 def from_mime_key(d):
148 """convert dict with mime-type keys to v3 aliases"""
149 for alias, mime in _mime_map.items():
150 if mime in d:
151 d[alias] = d.pop(mime)
152 return d
153
154 def upgrade_output(output):
155 """upgrade a single code cell output from v3 to v4
156
157 - pyout -> execute_result
158 - pyerr -> error
159 - output.type -> output.data.mime/type
160 - mime-type keys
161 - stream.stream -> stream.name
162 """
163 if output['output_type'] in {'pyout', 'display_data'}:
164 output.setdefault('metadata', NotebookNode())
165 if output['output_type'] == 'pyout':
166 output['output_type'] = 'execute_result'
167 output['execution_count'] = output.pop('prompt_number', None)
168
169 # move output data into data sub-dict
170 data = {}
171 for key in list(output):
172 if key in {'output_type', 'execution_count', 'metadata'}:
173 continue
174 data[key] = output.pop(key)
175 to_mime_key(data)
176 output['data'] = data
177 to_mime_key(output.metadata)
178 if 'application/json' in data:
179 data['application/json'] = json.loads(data['application/json'])
180 # promote ascii bytes (from v2) to unicode
181 for key in ('image/png', 'image/jpeg'):
182 if key in data and isinstance(data[key], bytes):
183 data[key] = data[key].decode('ascii')
184 elif output['output_type'] == 'pyerr':
185 output['output_type'] = 'error'
186 elif output['output_type'] == 'stream':
187 output['name'] = output.pop('stream')
188 return output
189
190 def downgrade_output(output):
191 """downgrade a single code cell output to v3 from v4
192
193 - pyout <- execute_result
194 - pyerr <- error
195 - output.data.mime/type -> output.type
196 - un-mime-type keys
197 - stream.stream <- stream.name
198 """
199 if output['output_type'] in {'execute_result', 'display_data'}:
200 if output['output_type'] == 'execute_result':
201 output['output_type'] = 'pyout'
202 output['prompt_number'] = output.pop('execution_count', None)
203
204 # promote data dict to top-level output namespace
205 data = output.pop('data', {})
206 if 'application/json' in data:
207 data['application/json'] = json.dumps(data['application/json'])
208 from_mime_key(data)
209 output.update(data)
210 from_mime_key(output.get('metadata', {}))
211 elif output['output_type'] == 'error':
212 output['output_type'] = 'pyerr'
213 elif output['output_type'] == 'stream':
214 output['stream'] = output.pop('name')
215 return output
216
217 def upgrade_outputs(outputs):
218 """upgrade outputs of a code cell from v3 to v4"""
219 return [upgrade_output(op) for op in outputs]
220
221 def downgrade_outputs(outputs):
222 """downgrade outputs of a code cell to v3 from v4"""
223 return [downgrade_output(op) for op in outputs]
224
225 def downgrade(nb):
226 """Convert a v4 notebook to v3.
227
228 Parameters
229 ----------
230 nb : NotebookNode
231 The Python representation of the notebook to convert.
232 """
233 if nb.nbformat != nbformat:
234 return nb
235
236 # Validate the notebook before conversion
237 _warn_if_invalid(nb, nbformat)
238
239 nb.nbformat = v3.nbformat
240 nb.nbformat_minor = v3.nbformat_minor
241 cells = [ downgrade_cell(cell) for cell in nb.pop('cells') ]
242 nb.worksheets = [v3.new_worksheet(cells=cells)]
243 nb.metadata.setdefault('name', '')
244 nb.metadata.pop('orig_nbformat', None)
245 nb.metadata.pop('orig_nbformat_minor', None)
246
247 # Validate the converted notebook before returning it
248 _warn_if_invalid(nb, v3.nbformat)
249 return nb
@@ -0,0 +1,137 b''
1 """Python API for composing notebook elements
2
3 The Python representation of a notebook is a nested structure of
4 dictionary subclasses that support attribute access
5 (IPython.utils.ipstruct.Struct). The functions in this module are merely
6 helpers to build the structs in the right form.
7 """
8
9 # Copyright (c) IPython Development Team.
10 # Distributed under the terms of the Modified BSD License.
11
12 from ..notebooknode import from_dict, NotebookNode
13
14 # Change this when incrementing the nbformat version
15 nbformat = 4
16 nbformat_minor = 0
17 nbformat_schema = 'nbformat.v4.schema.json'
18
19
20 def validate(node, ref=None):
21 """validate a v4 node"""
22 from .. import validate
23 return validate(node, ref=ref, version=nbformat)
24
25
26 def new_output(output_type, data=None, **kwargs):
27 """Create a new output, to go in the ``cell.outputs`` list of a code cell."""
28 output = NotebookNode(output_type=output_type)
29
30 # populate defaults:
31 if output_type == 'stream':
32 output.name = u'stdout'
33 output.text = u''
34 elif output_type in {'execute_result', 'display_data'}:
35 output.metadata = NotebookNode()
36 output.data = NotebookNode()
37 # load from args:
38 output.update(from_dict(kwargs))
39 if data is not None:
40 output.data = from_dict(data)
41 # validate
42 validate(output, output_type)
43 return output
44
45
46 def output_from_msg(msg):
47 """Create a NotebookNode for an output from a kernel's IOPub message.
48
49 Returns
50 -------
51
52 NotebookNode: the output as a notebook node.
53
54 Raises
55 ------
56
57 ValueError: if the message is not an output message.
58
59 """
60 msg_type = msg['header']['msg_type']
61 content = msg['content']
62
63 if msg_type == 'execute_result':
64 return new_output(output_type=msg_type,
65 metadata=content['metadata'],
66 data=content['data'],
67 execution_count=content['execution_count'],
68 )
69 elif msg_type == 'stream':
70 return new_output(output_type=msg_type,
71 name=content['name'],
72 text=content['text'],
73 )
74 elif msg_type == 'display_data':
75 return new_output(output_type=msg_type,
76 metadata=content['metadata'],
77 data=content['data'],
78 )
79 elif msg_type == 'error':
80 return new_output(output_type=msg_type,
81 ename=content['ename'],
82 evalue=content['evalue'],
83 traceback=content['traceback'],
84 )
85 else:
86 raise ValueError("Unrecognized output msg type: %r" % msg_type)
87
88
89 def new_code_cell(source='', **kwargs):
90 """Create a new code cell"""
91 cell = NotebookNode(
92 cell_type='code',
93 metadata=NotebookNode(),
94 execution_count=None,
95 source=source,
96 outputs=[],
97 )
98 cell.update(from_dict(kwargs))
99
100 validate(cell, 'code_cell')
101 return cell
102
103 def new_markdown_cell(source='', **kwargs):
104 """Create a new markdown cell"""
105 cell = NotebookNode(
106 cell_type='markdown',
107 source=source,
108 metadata=NotebookNode(),
109 )
110 cell.update(from_dict(kwargs))
111
112 validate(cell, 'markdown_cell')
113 return cell
114
115 def new_raw_cell(source='', **kwargs):
116 """Create a new raw cell"""
117 cell = NotebookNode(
118 cell_type='raw',
119 source=source,
120 metadata=NotebookNode(),
121 )
122 cell.update(from_dict(kwargs))
123
124 validate(cell, 'raw_cell')
125 return cell
126
127 def new_notebook(**kwargs):
128 """Create a new notebook"""
129 nb = NotebookNode(
130 nbformat=nbformat,
131 nbformat_minor=nbformat_minor,
132 metadata=NotebookNode(),
133 cells=[],
134 )
135 nb.update(from_dict(kwargs))
136 validate(nb)
137 return nb
@@ -0,0 +1,308 b''
1 {
2 "$schema": "http://json-schema.org/draft-04/schema#",
3 "description": "IPython Notebook v4.0 JSON schema.",
4 "type": "object",
5 "additionalProperties": false,
6 "required": ["metadata", "nbformat_minor", "nbformat", "cells"],
7 "properties": {
8 "metadata": {
9 "description": "Notebook root-level metadata.",
10 "type": "object",
11 "additionalProperties": true,
12 "properties": {
13 "kernel_info": {
14 "description": "Kernel information.",
15 "type": "object",
16 "required": ["name", "language"],
17 "properties": {
18 "name": {
19 "description": "Name of the kernel specification.",
20 "type": "string"
21 },
22 "language": {
23 "description": "The programming language which this kernel runs.",
24 "type": "string"
25 },
26 "codemirror_mode": {
27 "description": "The codemirror mode to use for code in this language.",
28 "type": "string"
29 }
30 }
31 },
32 "signature": {
33 "description": "Hash of the notebook.",
34 "type": "string"
35 },
36 "orig_nbformat": {
37 "description": "Original notebook format (major number) before converting the notebook between versions. This should never be written to a file.",
38 "type": "integer",
39 "minimum": 1
40 }
41 }
42 },
43 "nbformat_minor": {
44 "description": "Notebook format (minor number). Incremented for backward compatible changes to the notebook format.",
45 "type": "integer",
46 "minimum": 0
47 },
48 "nbformat": {
49 "description": "Notebook format (major number). Incremented between backwards incompatible changes to the notebook format.",
50 "type": "integer",
51 "minimum": 4,
52 "maximum": 4
53 },
54 "cells": {
55 "description": "Array of cells of the current notebook.",
56 "type": "array",
57 "items": {
58 "type": "object",
59 "oneOf": [
60 {"$ref": "#/definitions/raw_cell"},
61 {"$ref": "#/definitions/markdown_cell"},
62 {"$ref": "#/definitions/code_cell"}
63 ]
64 }
65 }
66 },
67
68 "definitions": {
69
70 "raw_cell": {
71 "description": "Notebook raw nbconvert cell.",
72 "type": "object",
73 "additionalProperties": false,
74 "required": ["cell_type", "metadata", "source"],
75 "properties": {
76 "cell_type": {
77 "description": "String identifying the type of cell.",
78 "enum": ["raw"]
79 },
80 "metadata": {
81 "description": "Cell-level metadata.",
82 "type": "object",
83 "additionalProperties": true,
84 "properties": {
85 "format": {
86 "description": "Raw cell metadata format for nbconvert.",
87 "type": "string"
88 },
89 "name": {"$ref": "#/definitions/misc/metadata_name"},
90 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
91 }
92 },
93 "source": {"$ref": "#/definitions/misc/source"}
94 }
95 },
96
97 "markdown_cell": {
98 "description": "Notebook markdown cell.",
99 "type": "object",
100 "additionalProperties": false,
101 "required": ["cell_type", "metadata", "source"],
102 "properties": {
103 "cell_type": {
104 "description": "String identifying the type of cell.",
105 "enum": ["markdown"]
106 },
107 "metadata": {
108 "description": "Cell-level metadata.",
109 "type": "object",
110 "properties": {
111 "name": {"$ref": "#/definitions/misc/metadata_name"},
112 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
113 },
114 "additionalProperties": true
115 },
116 "source": {"$ref": "#/definitions/misc/source"}
117 }
118 },
119
120 "code_cell": {
121 "description": "Notebook code cell.",
122 "type": "object",
123 "additionalProperties": false,
124 "required": ["cell_type", "metadata", "source", "outputs", "execution_count"],
125 "properties": {
126 "cell_type": {
127 "description": "String identifying the type of cell.",
128 "enum": ["code"]
129 },
130 "metadata": {
131 "description": "Cell-level metadata.",
132 "type": "object",
133 "additionalProperties": true,
134 "properties": {
135 "collapsed": {
136 "description": "Whether the cell is collapsed/expanded.",
137 "type": "boolean"
138 },
139 "autoscroll": {
140 "description": "Whether the cell's output is scrolled, unscrolled, or autoscrolled.",
141 "enum": [true, false, "auto"]
142 },
143 "name": {"$ref": "#/definitions/misc/metadata_name"},
144 "tags": {"$ref": "#/definitions/misc/metadata_tags"}
145 }
146 },
147 "source": {"$ref": "#/definitions/misc/source"},
148 "outputs": {
149 "description": "Execution, display, or stream outputs.",
150 "type": "array",
151 "items": {"$ref": "#/definitions/output"}
152 },
153 "execution_count": {
154 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
155 "type": ["integer", "null"],
156 "minimum": 0
157 }
158 }
159 },
160 "output": {
161 "type": "object",
162 "oneOf": [
163 {"$ref": "#/definitions/execute_result"},
164 {"$ref": "#/definitions/display_data"},
165 {"$ref": "#/definitions/stream"},
166 {"$ref": "#/definitions/error"}
167 ]
168 },
169
170 "execute_result": {
171 "description": "Result of executing a code cell.",
172 "type": "object",
173 "additionalProperties": false,
174 "required": ["output_type", "data", "metadata", "execution_count"],
175 "properties": {
176 "output_type": {
177 "description": "Type of cell output.",
178 "enum": ["execute_result"]
179 },
180 "execution_count": {
181 "description": "A result's prompt number.",
182 "type": ["integer", "null"],
183 "minimum": 0
184 },
185 "data": {"$ref": "#/definitions/misc/mimebundle"},
186 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
187 }
188 },
189
190 "display_data": {
191 "description": "Data displayed as a result of code cell execution.",
192 "type": "object",
193 "additionalProperties": false,
194 "required": ["output_type", "data", "metadata"],
195 "properties": {
196 "output_type": {
197 "description": "Type of cell output.",
198 "enum": ["display_data"]
199 },
200 "data": {"$ref": "#/definitions/misc/mimebundle"},
201 "metadata": {"$ref": "#/definitions/misc/output_metadata"}
202 }
203 },
204
205 "stream": {
206 "description": "Stream output from a code cell.",
207 "type": "object",
208 "additionalProperties": false,
209 "required": ["output_type", "name", "text"],
210 "properties": {
211 "output_type": {
212 "description": "Type of cell output.",
213 "enum": ["stream"]
214 },
215 "name": {
216 "description": "The name of the stream (stdout, stderr).",
217 "type": "string"
218 },
219 "text": {
220 "description": "The stream's text output, represented as an array of strings.",
221 "$ref": "#/definitions/misc/multiline_string"
222 }
223 }
224 },
225
226 "error": {
227 "description": "Output of an error that occurred during code cell execution.",
228 "type": "object",
229 "additionalProperties": false,
230 "required": ["output_type", "ename", "evalue", "traceback"],
231 "properties": {
232 "output_type": {
233 "description": "Type of cell output.",
234 "enum": ["error"]
235 },
236 "ename": {
237 "description": "The name of the error.",
238 "type": "string"
239 },
240 "evalue": {
241 "description": "The value, or message, of the error.",
242 "type": "string"
243 },
244 "traceback": {
245 "description": "The error's traceback, represented as an array of strings.",
246 "type": "array",
247 "items": {"type": "string"}
248 }
249 }
250 },
251
252 "misc": {
253 "metadata_name": {
254 "description": "The cell's name. If present, must be a non-empty string.",
255 "type": "string",
256 "pattern": "^.+$"
257 },
258 "metadata_tags": {
259 "description": "The cell's tags. Tags must be unique, and must not contain commas.",
260 "type": "array",
261 "uniqueItems": true,
262 "items": {
263 "type": "string",
264 "pattern": "^[^,]+$"
265 }
266 },
267 "source": {
268 "description": "Contents of the cell, represented as an array of lines.",
269 "$ref": "#/definitions/misc/multiline_string"
270 },
271 "execution_count": {
272 "description": "The code cell's prompt number. Will be null if the cell has not been run.",
273 "type": ["integer", "null"],
274 "minimum": 0
275 },
276 "mimebundle": {
277 "description": "A mime-type keyed dictionary of data",
278 "type": "object",
279 "additionalProperties": false,
280 "properties": {
281 "application/json": {
282 "type": "object"
283 }
284 },
285 "patternProperties": {
286 "^(?!application/json$)[a-zA-Z0-9]+/[a-zA-Z0-9\\-\\+\\.]+$": {
287 "description": "mimetype output (e.g. text/plain), represented as either an array of strings or a string.",
288 "$ref": "#/definitions/misc/multiline_string"
289 }
290 }
291 },
292 "output_metadata": {
293 "description": "Cell output metadata.",
294 "type": "object",
295 "additionalProperties": true
296 },
297 "multiline_string": {
298 "oneOf" : [
299 {"type": "string"},
300 {
301 "type": "array",
302 "items": {"type": "string"}
303 }
304 ]
305 }
306 }
307 }
308 }
@@ -0,0 +1,67 b''
1 """Read and write notebooks in JSON format."""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 import copy
7 import json
8
9 from IPython.utils import py3compat
10
11 from .nbbase import from_dict
12 from .rwbase import (
13 NotebookReader, NotebookWriter, rejoin_lines, split_lines, strip_transient
14 )
15
16
17 class BytesEncoder(json.JSONEncoder):
18 """A JSON encoder that accepts b64 (and other *ascii*) bytestrings."""
19 def default(self, obj):
20 if isinstance(obj, bytes):
21 return obj.decode('ascii')
22 return json.JSONEncoder.default(self, obj)
23
24
25 class JSONReader(NotebookReader):
26
27 def reads(self, s, **kwargs):
28 """Read a JSON string into a Notebook object"""
29 nb = json.loads(s, **kwargs)
30 nb = self.to_notebook(nb, **kwargs)
31 return nb
32
33 def to_notebook(self, d, **kwargs):
34 """Convert a disk-format notebook dict to in-memory NotebookNode
35
36 handles multi-line values as strings, scrubbing of transient values, etc.
37 """
38 nb = from_dict(d)
39 nb = rejoin_lines(nb)
40 nb = strip_transient(nb)
41 return nb
42
43
44 class JSONWriter(NotebookWriter):
45
46 def writes(self, nb, **kwargs):
47 """Serialize a NotebookNode object as a JSON string"""
48 kwargs['cls'] = BytesEncoder
49 kwargs['indent'] = 1
50 kwargs['sort_keys'] = True
51 kwargs['separators'] = (',',': ')
52 # don't modify in-memory dict
53 nb = copy.deepcopy(nb)
54 if kwargs.pop('split_lines', True):
55 nb = split_lines(nb)
56 nb = strip_transient(nb)
57 return py3compat.str_to_unicode(json.dumps(nb, **kwargs), 'utf-8')
58
59
60 _reader = JSONReader()
61 _writer = JSONWriter()
62
63 reads = _reader.reads
64 read = _reader.read
65 to_notebook = _reader.to_notebook
66 write = _writer.write
67 writes = _writer.writes
@@ -0,0 +1,95 b''
1 """Base classes and utilities for readers and writers."""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 from IPython.utils.py3compat import string_types, cast_unicode_py2
7
8
9 def rejoin_lines(nb):
10 """rejoin multiline text into strings
11
12 For reversing effects of ``split_lines(nb)``.
13
14 This only rejoins lines that have been split, so if text objects were not split
15 they will pass through unchanged.
16
17 Used when reading JSON files that may have been passed through split_lines.
18 """
19 for cell in nb.cells:
20 if 'source' in cell and isinstance(cell.source, list):
21 cell.source = ''.join(cell.source)
22 if cell.get('cell_type', None) == 'code':
23 for output in cell.get('outputs', []):
24 output_type = output.get('output_type', '')
25 if output_type in {'execute_result', 'display_data'}:
26 for key, value in output.get('data', {}).items():
27 if key != 'application/json' and isinstance(value, list):
28 output.data[key] = ''.join(value)
29 elif output_type:
30 if isinstance(output.get('text', ''), list):
31 output.text = ''.join(output.text)
32 return nb
33
34
35 def split_lines(nb):
36 """split likely multiline text into lists of strings
37
38 For file output more friendly to line-based VCS. ``rejoin_lines(nb)`` will
39 reverse the effects of ``split_lines(nb)``.
40
41 Used when writing JSON files.
42 """
43 for cell in nb.cells:
44 source = cell.get('source', None)
45 if isinstance(source, string_types):
46 cell['source'] = source.splitlines(True)
47
48 if cell.cell_type == 'code':
49 for output in cell.outputs:
50 if output.output_type in {'execute_result', 'display_data'}:
51 for key, value in output.data.items():
52 if key != 'application/json' and isinstance(value, string_types):
53 output.data[key] = value.splitlines(True)
54 elif output.output_type == 'stream':
55 if isinstance(output.text, string_types):
56 output.text = output.text.splitlines(True)
57 return nb
58
59
60 def strip_transient(nb):
61 """Strip transient values that shouldn't be stored in files.
62
63 This should be called in *both* read and write.
64 """
65 nb.metadata.pop('orig_nbformat', None)
66 nb.metadata.pop('orig_nbformat_minor', None)
67 for cell in nb.cells:
68 cell.metadata.pop('trusted', None)
69 return nb
70
71
72 class NotebookReader(object):
73 """A class for reading notebooks."""
74
75 def reads(self, s, **kwargs):
76 """Read a notebook from a string."""
77 raise NotImplementedError("loads must be implemented in a subclass")
78
79 def read(self, fp, **kwargs):
80 """Read a notebook from a file like object"""
81 nbs = cast_unicode_py2(fp.read())
82 return self.reads(nbs, **kwargs)
83
84
85 class NotebookWriter(object):
86 """A class for writing notebooks."""
87
88 def writes(self, nb, **kwargs):
89 """Write a notebook to a string."""
90 raise NotImplementedError("loads must be implemented in a subclass")
91
92 def write(self, nb, fp, **kwargs):
93 """Write a notebook to a file like object"""
94 nbs = cast_unicode_py2(self.writes(nb, **kwargs))
95 return fp.write(nbs)
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,54 b''
1 # -*- coding: utf8 -*-
2 import io
3 import os
4 import shutil
5 import tempfile
6
7 pjoin = os.path.join
8
9 from .nbexamples import nb0
10
11
12 def open_utf8(fname, mode):
13 return io.open(fname, mode=mode, encoding='utf-8')
14
15 class NBFormatTest:
16 """Mixin for writing notebook format tests"""
17
18 # override with appropriate values in subclasses
19 nb0_ref = None
20 ext = None
21 mod = None
22
23 def setUp(self):
24 self.wd = tempfile.mkdtemp()
25
26 def tearDown(self):
27 shutil.rmtree(self.wd)
28
29 def assertNBEquals(self, nba, nbb):
30 self.assertEqual(nba, nbb)
31
32 def test_writes(self):
33 s = self.mod.writes(nb0)
34 if self.nb0_ref:
35 self.assertEqual(s, self.nb0_ref)
36
37 def test_reads(self):
38 s = self.mod.writes(nb0)
39 nb = self.mod.reads(s)
40
41 def test_roundtrip(self):
42 s = self.mod.writes(nb0)
43 self.assertNBEquals(self.mod.reads(s),nb0)
44
45 def test_write_file(self):
46 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f:
47 self.mod.write(nb0, f)
48
49 def test_read_file(self):
50 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'w') as f:
51 self.mod.write(nb0, f)
52
53 with open_utf8(pjoin(self.wd, "nb0.%s" % self.ext), 'r') as f:
54 nb = self.mod.read(f)
@@ -0,0 +1,104 b''
1 # -*- coding: utf-8 -*-
2
3 import os
4 from base64 import encodestring
5
6 from ..nbbase import (
7 new_code_cell, new_markdown_cell, new_notebook,
8 new_output, new_raw_cell
9 )
10
11 # some random base64-encoded *text*
12 png = encodestring(os.urandom(5)).decode('ascii')
13 jpeg = encodestring(os.urandom(6)).decode('ascii')
14
15 cells = []
16 cells.append(new_markdown_cell(
17 source='Some NumPy Examples',
18 ))
19
20
21 cells.append(new_code_cell(
22 source='import numpy',
23 execution_count=1,
24 ))
25
26 cells.append(new_markdown_cell(
27 source='A random array',
28 ))
29
30 cells.append(new_raw_cell(
31 source='A random array',
32 ))
33
34 cells.append(new_markdown_cell(
35 source=u'## My Heading',
36 ))
37
38 cells.append(new_code_cell(
39 source='a = numpy.random.rand(100)',
40 execution_count=2,
41 ))
42 cells.append(new_code_cell(
43 source='a = 10\nb = 5\n',
44 execution_count=3,
45 ))
46 cells.append(new_code_cell(
47 source='a = 10\nb = 5',
48 execution_count=4,
49 ))
50
51 cells.append(new_code_cell(
52 source=u'print "ünîcødé"',
53 execution_count=3,
54 outputs=[new_output(
55 output_type=u'execute_result',
56 data={
57 'text/plain': u'<array a>',
58 'text/html': u'The HTML rep',
59 'text/latex': u'$a$',
60 'image/png': png,
61 'image/jpeg': jpeg,
62 'image/svg+xml': u'<svg>',
63 'application/json': {
64 'key': 'value'
65 },
66 'application/javascript': u'var i=0;'
67 },
68 execution_count=3
69 ),new_output(
70 output_type=u'display_data',
71 data={
72 'text/plain': u'<array a>',
73 'text/html': u'The HTML rep',
74 'text/latex': u'$a$',
75 'image/png': png,
76 'image/jpeg': jpeg,
77 'image/svg+xml': u'<svg>',
78 'application/json': {
79 'key': 'value'
80 },
81 'application/javascript': u'var i=0;'
82 },
83 ),new_output(
84 output_type=u'error',
85 ename=u'NameError',
86 evalue=u'NameError was here',
87 traceback=[u'frame 0', u'frame 1', u'frame 2']
88 ),new_output(
89 output_type=u'stream',
90 text='foo\rbar\r\n'
91 ),new_output(
92 output_type=u'stream',
93 name='stderr',
94 text='\rfoo\rbar\n'
95 )]
96 ))
97
98 nb0 = new_notebook(cells=cells,
99 metadata={
100 'language': 'python',
101 }
102 )
103
104
@@ -0,0 +1,67 b''
1 import copy
2
3 import nose.tools as nt
4
5 from IPython.nbformat import validate
6 from .. import convert
7
8 from . import nbexamples
9 from IPython.nbformat.v3.tests import nbexamples as v3examples
10 from IPython.nbformat import v3, v4
11
12 def test_upgrade_notebook():
13 nb03 = copy.deepcopy(v3examples.nb0)
14 validate(nb03)
15 nb04 = convert.upgrade(nb03)
16 validate(nb04)
17
18 def test_downgrade_notebook():
19 nb04 = copy.deepcopy(nbexamples.nb0)
20 validate(nb04)
21 nb03 = convert.downgrade(nb04)
22 validate(nb03)
23
24 def test_upgrade_heading():
25 v3h = v3.new_heading_cell
26 v4m = v4.new_markdown_cell
27 for v3cell, expected in [
28 (
29 v3h(source='foo', level=1),
30 v4m(source='# foo'),
31 ),
32 (
33 v3h(source='foo\nbar\nmulti-line\n', level=4),
34 v4m(source='#### foo bar multi-line'),
35 ),
36 ]:
37 upgraded = convert.upgrade_cell(v3cell)
38 nt.assert_equal(upgraded, expected)
39
40 def test_downgrade_heading():
41 v3h = v3.new_heading_cell
42 v4m = v4.new_markdown_cell
43 v3m = lambda source: v3.new_text_cell('markdown', source)
44 for v4cell, expected in [
45 (
46 v4m(source='# foo'),
47 v3h(source='foo', level=1),
48 ),
49 (
50 v4m(source='#foo'),
51 v3h(source='foo', level=1),
52 ),
53 (
54 v4m(source='#\tfoo'),
55 v3h(source='foo', level=1),
56 ),
57 (
58 v4m(source='# \t foo'),
59 v3h(source='foo', level=1),
60 ),
61 (
62 v4m(source='# foo\nbar'),
63 v3m(source='# foo\nbar'),
64 ),
65 ]:
66 downgraded = convert.downgrade_cell(v4cell)
67 nt.assert_equal(downgraded, expected)
@@ -0,0 +1,69 b''
1 from base64 import decodestring
2 from unittest import TestCase
3
4 from IPython.utils.py3compat import unicode_type
5 from ..nbjson import reads, writes
6 from .. import nbjson
7 from .nbexamples import nb0
8
9 from . import formattest
10
11
12 class TestJSON(formattest.NBFormatTest, TestCase):
13
14 nb0_ref = None
15 ext = 'ipynb'
16 mod = nbjson
17
18 def test_roundtrip_nosplit(self):
19 """Ensure that multiline blobs are still readable"""
20 # ensures that notebooks written prior to splitlines change
21 # are still readable.
22 s = writes(nb0, split_lines=False)
23 self.assertEqual(nbjson.reads(s),nb0)
24
25 def test_roundtrip_split(self):
26 """Ensure that splitting multiline blocks is safe"""
27 # This won't differ from test_roundtrip unless the default changes
28 s = writes(nb0, split_lines=True)
29 self.assertEqual(nbjson.reads(s),nb0)
30
31 def test_read_png(self):
32 """PNG output data is b64 unicode"""
33 s = writes(nb0)
34 nb1 = nbjson.reads(s)
35 found_png = False
36 for cell in nb1.cells:
37 if not 'outputs' in cell:
38 continue
39 for output in cell.outputs:
40 if not 'data' in output:
41 continue
42 if 'image/png' in output.data:
43 found_png = True
44 pngdata = output.data['image/png']
45 self.assertEqual(type(pngdata), unicode_type)
46 # test that it is valid b64 data
47 b64bytes = pngdata.encode('ascii')
48 raw_bytes = decodestring(b64bytes)
49 assert found_png, "never found png output"
50
51 def test_read_jpeg(self):
52 """JPEG output data is b64 unicode"""
53 s = writes(nb0)
54 nb1 = nbjson.reads(s)
55 found_jpeg = False
56 for cell in nb1.cells:
57 if not 'outputs' in cell:
58 continue
59 for output in cell.outputs:
60 if not 'data' in output:
61 continue
62 if 'image/jpeg' in output.data:
63 found_jpeg = True
64 jpegdata = output.data['image/jpeg']
65 self.assertEqual(type(jpegdata), unicode_type)
66 # test that it is valid b64 data
67 b64bytes = jpegdata.encode('ascii')
68 raw_bytes = decodestring(b64bytes)
69 assert found_jpeg, "never found jpeg output"
@@ -0,0 +1,101 b''
1 # coding: utf-8
2 """Tests for the Python API for composing notebook elements"""
3
4 import nose.tools as nt
5
6 from IPython.nbformat.validator import isvalid, validate, ValidationError
7 from ..nbbase import (
8 NotebookNode, nbformat,
9 new_code_cell, new_markdown_cell, new_notebook,
10 new_output, new_raw_cell,
11 )
12
13 def test_empty_notebook():
14 nb = new_notebook()
15 nt.assert_equal(nb.cells, [])
16 nt.assert_equal(nb.metadata, NotebookNode())
17 nt.assert_equal(nb.nbformat, nbformat)
18
19 def test_empty_markdown_cell():
20 cell = new_markdown_cell()
21 nt.assert_equal(cell.cell_type, 'markdown')
22 nt.assert_equal(cell.source, '')
23
24 def test_markdown_cell():
25 cell = new_markdown_cell(u'* Søme markdown')
26 nt.assert_equal(cell.source, u'* Søme markdown')
27
28 def test_empty_raw_cell():
29 cell = new_raw_cell()
30 nt.assert_equal(cell.cell_type, u'raw')
31 nt.assert_equal(cell.source, '')
32
33 def test_raw_cell():
34 cell = new_raw_cell('hi')
35 nt.assert_equal(cell.source, u'hi')
36
37 def test_empty_code_cell():
38 cell = new_code_cell('hi')
39 nt.assert_equal(cell.cell_type, 'code')
40 nt.assert_equal(cell.source, u'hi')
41
42 def test_empty_display_data():
43 output = new_output('display_data')
44 nt.assert_equal(output.output_type, 'display_data')
45
46 def test_empty_stream():
47 output = new_output('stream')
48 nt.assert_equal(output.output_type, 'stream')
49 nt.assert_equal(output.name, 'stdout')
50 nt.assert_equal(output.text, '')
51
52 def test_empty_execute_result():
53 output = new_output('execute_result', execution_count=1)
54 nt.assert_equal(output.output_type, 'execute_result')
55
56 mimebundle = {
57 'text/plain': "some text",
58 "application/json": {
59 "key": "value"
60 },
61 "image/svg+xml": 'ABCDEF',
62 "application/octet-stream": 'ABC-123',
63 "application/vnd.foo+bar": "Some other stuff",
64 }
65
66 def test_display_data():
67 output = new_output('display_data', mimebundle)
68 for key, expected in mimebundle.items():
69 nt.assert_equal(output.data[key], expected)
70
71 def test_execute_result():
72 output = new_output('execute_result', mimebundle, execution_count=10)
73 nt.assert_equal(output.execution_count, 10)
74 for key, expected in mimebundle.items():
75 nt.assert_equal(output.data[key], expected)
76
77 def test_error():
78 o = new_output(output_type=u'error', ename=u'NameError',
79 evalue=u'Name not found', traceback=[u'frame 0', u'frame 1', u'frame 2']
80 )
81 nt.assert_equal(o.output_type, u'error')
82 nt.assert_equal(o.ename, u'NameError')
83 nt.assert_equal(o.evalue, u'Name not found')
84 nt.assert_equal(o.traceback, [u'frame 0', u'frame 1', u'frame 2'])
85
86 def test_code_cell_with_outputs():
87 cell = new_code_cell(execution_count=10, outputs=[
88 new_output('display_data', mimebundle),
89 new_output('stream', text='hello'),
90 new_output('execute_result', mimebundle, execution_count=10),
91 ])
92 nt.assert_equal(cell.execution_count, 10)
93 nt.assert_equal(len(cell.outputs), 3)
94 er = cell.outputs[-1]
95 nt.assert_equal(er.execution_count, 10)
96 nt.assert_equal(er['output_type'], 'execute_result')
97
98 def test_stream():
99 output = new_output('stream', name='stderr', text='hello there')
100 nt.assert_equal(output.name, 'stderr')
101 nt.assert_equal(output.text, 'hello there')
@@ -0,0 +1,105 b''
1 """Tests for nbformat validation"""
2
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
5
6 import io
7 import os
8
9 import nose.tools as nt
10
11 from IPython.nbformat.validator import validate, ValidationError
12 from ..nbjson import reads
13 from ..nbbase import (
14 nbformat,
15 new_code_cell, new_markdown_cell, new_notebook,
16 new_output, new_raw_cell,
17 )
18
19 def validate4(obj, ref=None):
20 return validate(obj, ref, version=nbformat)
21
22 def test_valid_code_cell():
23 cell = new_code_cell()
24 validate4(cell, 'code_cell')
25
26 def test_invalid_code_cell():
27 cell = new_code_cell()
28
29 cell['source'] = 5
30 with nt.assert_raises(ValidationError):
31 validate4(cell, 'code_cell')
32
33 cell = new_code_cell()
34 del cell['metadata']
35
36 with nt.assert_raises(ValidationError):
37 validate4(cell, 'code_cell')
38
39 cell = new_code_cell()
40 del cell['source']
41
42 with nt.assert_raises(ValidationError):
43 validate4(cell, 'code_cell')
44
45 cell = new_code_cell()
46 del cell['cell_type']
47
48 with nt.assert_raises(ValidationError):
49 validate4(cell, 'code_cell')
50
51 def test_invalid_markdown_cell():
52 cell = new_markdown_cell()
53
54 cell['source'] = 5
55 with nt.assert_raises(ValidationError):
56 validate4(cell, 'markdown_cell')
57
58 cell = new_markdown_cell()
59 del cell['metadata']
60
61 with nt.assert_raises(ValidationError):
62 validate4(cell, 'markdown_cell')
63
64 cell = new_markdown_cell()
65 del cell['source']
66
67 with nt.assert_raises(ValidationError):
68 validate4(cell, 'markdown_cell')
69
70 cell = new_markdown_cell()
71 del cell['cell_type']
72
73 with nt.assert_raises(ValidationError):
74 validate4(cell, 'markdown_cell')
75
76 def test_invalid_raw_cell():
77 cell = new_raw_cell()
78
79 cell['source'] = 5
80 with nt.assert_raises(ValidationError):
81 validate4(cell, 'raw_cell')
82
83 cell = new_raw_cell()
84 del cell['metadata']
85
86 with nt.assert_raises(ValidationError):
87 validate4(cell, 'raw_cell')
88
89 cell = new_raw_cell()
90 del cell['source']
91
92 with nt.assert_raises(ValidationError):
93 validate4(cell, 'raw_cell')
94
95 cell = new_raw_cell()
96 del cell['cell_type']
97
98 with nt.assert_raises(ValidationError):
99 validate4(cell, 'raw_cell')
100
101 def test_sample_notebook():
102 here = os.path.dirname(__file__)
103 with io.open(os.path.join(here, os.pardir, os.pardir, 'tests', "test4.ipynb"), encoding='utf-8') as f:
104 nb = reads(f.read())
105 validate4(nb)
@@ -0,0 +1,338 b''
1 .. _nbformat:
2
3 ===========================
4 The Jupyter Notebook Format
5 ===========================
6
7 Introduction
8 ============
9
10 Jupyter (né IPython) notebook files are simple JSON documents,
11 containing text, source code, rich media output, and metadata.
12 each segment of the document is stored in a cell.
13
14 Some general points about the notebook format:
15
16 .. note::
17
18 *All* metadata fields are optional.
19 While the type and values of some metadata are defined,
20 no metadata values are required to be defined.
21
22
23 Top-level structure
24 ===================
25
26 At the highest level, a Jupyter notebook is a dictionary with a few keys:
27
28 - metadata (dict)
29 - nbformat (int)
30 - nbformat_minor (int)
31 - cells (list)
32
33 .. sourcecode:: python
34
35 {
36 "metadata" : {
37 "signature": "hex-digest", # used for authenticating unsafe outputs on load
38 "kernel_info": {
39 # if kernel_info is defined, its name and language fields are required.
40 "name" : "the name of the kernel",
41 "language" : "the programming language of the kernel",
42 "codemirror_mode": "The name of the codemirror mode to use [optional]"
43 },
44 },
45 "nbformat": 4,
46 "nbformat_minor": 0,
47 "cells" : [
48 # list of cell dictionaries, see below
49 ],
50 }
51
52 Some fields, such as code input and text output, are characteristically multi-line strings.
53 When these fields are written to disk, they **may** be written as a list of strings,
54 which should be joined with ``''`` when reading back into memory.
55 In programmatic APIs for working with notebooks (Python, Javascript),
56 these are always re-joined into the original multi-line string.
57 If you intend to work with notebook files directly,
58 you must allow multi-line string fields to be either a string or list of strings.
59
60
61 Cell Types
62 ==========
63
64 There are a few basic cell types for encapsulating code and text.
65 All cells have the following basic structure:
66
67 .. sourcecode:: python
68
69 {
70 "cell_type" : "name",
71 "metadata" : {},
72 "source" : "single string or [list, of, strings]",
73 }
74
75
76 Markdown cells
77 --------------
78
79 Markdown cells are used for body-text, and contain markdown,
80 as defined in `GitHub-flavored markdown`_, and implemented in marked_.
81
82 .. _GitHub-flavored markdown: https://help.github.com/articles/github-flavored-markdown
83 .. _marked: https://github.com/chjj/marked
84
85 .. sourcecode:: python
86
87 {
88 "cell_type" : "markdown",
89 "metadata" : {},
90 "source" : ["some *markdown*"],
91 }
92
93 .. versionchanged:: nbformat 4.0
94
95 Heading cells have been removed, in favor of simple headings in markdown.
96
97
98 Code cells
99 ----------
100
101 Code cells are the primary content of Jupyter notebooks.
102 They contain source code in the language of the document's associated kernel,
103 and a list of outputs associated with executing that code.
104 They also have an execution_count, which must be an integer or ``null``.
105
106 .. sourcecode:: python
107
108 {
109 "cell_type" : "code",
110 "execution_count": 1, # integer or null
111 "metadata" : {
112 "collapsed" : True, # whether the output of the cell is collapsed
113 "autoscroll": False, # any of true, false or "auto"
114 },
115 "source" : ["some code"],
116 "outputs": [{
117 # list of output dicts (described below)
118 "output_type": "stream",
119 ...
120 }],
121 }
122
123 .. versionchanged:: nbformat 4.0
124
125 ``input`` was renamed to ``source``, for consistency among cell types.
126
127 .. versionchanged:: nbformat 4.0
128
129 ``prompt_number`` renamed to ``execution_count``
130
131 Code cell outputs
132 -----------------
133
134 A code cell can have a variety of outputs (stream data or rich mime-type output).
135 These correspond to :ref:`messages <messaging>` produced as a result of executing the cell.
136
137 All outputs have an ``output_type`` field,
138 which is a string defining what type of output it is.
139
140
141 stream output
142 *************
143
144 .. sourcecode:: python
145
146 {
147 "output_type" : "stream",
148 "name" : "stdout", # or stderr
149 "data" : ["multiline stream text"],
150 }
151
152 .. versionchanged:: nbformat 4.0
153
154 The keys ``stream`` and ``text`` were changed to ``name`` and ``data`` to match
155 the stream message specification.
156
157
158 display_data
159 ************
160
161 Rich display outputs, as created by ``display_data`` messages,
162 contain data keyed by mime-type. This is often called a mime-bundle,
163 and shows up in various locations in the notebook format and message spec.
164 The metadata of these messages may be keyed by mime-type as well.
165
166
167
168 .. sourcecode:: python
169
170 {
171 "output_type" : "display_data",
172 "data" : {
173 "text/plain" : ["multiline text data"],
174 "image/png": ["base64-encoded-png-data"],
175 "application/json": {
176 # JSON data is included as-is
177 "json": "data",
178 },
179 },
180 "metadata" : {
181 "image/png": {
182 "width": 640,
183 "height": 480,
184 },
185 },
186 }
187
188
189 .. versionchanged:: nbformat 4.0
190
191 ``application/json`` output is no longer double-serialized into a string.
192
193 .. versionchanged:: nbformat 4.0
194
195 mime-types are used for keys, instead of a combination of short names (``text``)
196 and mime-types, and are stored in a ``data`` key, rather than the top-level.
197 i.e. ``output.data['image/png']`` instead of ``output.png``.
198
199
200 execute_result
201 **************
202
203 Results of executing a cell (as created by ``displayhook`` in Python)
204 are stored in ``execute_result`` outputs.
205 `execute_result` outputs are identical to ``display_data``,
206 adding only a ``execution_count`` field, which must be an integer.
207
208 .. sourcecode:: python
209
210 {
211 "output_type" : "execute_result",
212 "execution_count": 42,
213 "data" : {
214 "text/plain" : ["multiline text data"],
215 "image/png": ["base64-encoded-png-data"],
216 "application/json": {
217 # JSON data is included as-is
218 "json": "data",
219 },
220 },
221 "metadata" : {
222 "image/png": {
223 "width": 640,
224 "height": 480,
225 },
226 },
227 }
228
229 .. versionchanged:: nbformat 4.0
230
231 ``pyout`` renamed to ``execute_result``
232
233 .. versionchanged:: nbformat 4.0
234
235 ``prompt_number`` renamed to ``execution_count``
236
237
238 error
239 *****
240
241 Failed execution may show a traceback
242
243 .. sourcecode:: python
244
245 {
246 'ename' : str, # Exception name, as a string
247 'evalue' : str, # Exception value, as a string
248
249 # The traceback will contain a list of frames,
250 # represented each as a string.
251 'traceback' : list,
252 }
253
254 .. versionchanged:: nbformat 4.0
255
256 ``pyerr`` renamed to ``error``
257
258
259 .. _raw nbconvert cells:
260
261 Raw NBConvert cells
262 -------------------
263
264 A raw cell is defined as content that should be included *unmodified* in :ref:`nbconvert <nbconvert>` output.
265 For example, this cell could include raw LaTeX for nbconvert to pdf via latex,
266 or restructured text for use in Sphinx documentation.
267
268 The notebook authoring environment does not render raw cells.
269
270 The only logic in a raw cell is the `format` metadata field.
271 If defined, it specifies which nbconvert output format is the intended target
272 for the raw cell. When outputting to any other format,
273 the raw cell's contents will be excluded.
274 In the default case when this value is undefined,
275 a raw cell's contents will be included in any nbconvert output,
276 regardless of format.
277
278 .. sourcecode:: python
279
280 {
281 "cell_type" : "raw",
282 "metadata" : {
283 # the mime-type of the target nbconvert format.
284 # nbconvert to formats other than this will exclude this cell.
285 "format" : "mime/type"
286 },
287 "source" : ["some nbformat mime-type data"]
288 }
289
290 Metadata
291 ========
292
293 Metadata is a place that you can put arbitrary JSONable information about
294 your notebook, cell, or output. Because it is a shared namespace,
295 any custom metadata should use a sufficiently unique namespace,
296 such as `metadata.kaylees_md.foo = "bar"`.
297
298 Metadata fields officially defined for Jupyter notebooks are listed here:
299
300 Notebook metadata
301 -----------------
302
303 The following metadata keys are defined at the notebook level:
304
305 =========== =============== ==============
306 Key Value Interpretation
307 =========== =============== ==============
308 kernelspec dict A :ref:`kernel specification <kernelspecs>`
309 signature str A hashed :ref:`signature <notebook_security>` of the notebook
310 =========== =============== ==============
311
312
313 Cell metadata
314 -------------
315
316 The following metadata keys are defined at the cell level:
317
318 =========== =============== ==============
319 Key Value Interpretation
320 =========== =============== ==============
321 collapsed bool Whether the cell's output container should be collapsed
322 autoscroll bool or 'auto' Whether the cell's output is scrolled, unscrolled, or autoscrolled
323 deletable bool If False, prevent deletion of the cell
324 format 'mime/type' The mime-type of a :ref:`Raw NBConvert Cell <raw nbconvert cells>`
325 name str A name for the cell. Should be unique
326 tags list of str A list of string tags on the cell. Commas are not allowed in a tag
327 =========== =============== ==============
328
329 Output metadata
330 ---------------
331
332 The following metadata keys are defined for code cell outputs:
333
334 =========== =============== ==============
335 Key Value Interpretation
336 =========== =============== ==============
337 isolated bool Whether the output should be isolated into an IFrame
338 =========== =============== ==============
@@ -2649,14 +2649,14 b' class InteractiveShell(SingletonConfigurable):'
2649 def get_cells():
2649 def get_cells():
2650 """generator for sequence of code blocks to run"""
2650 """generator for sequence of code blocks to run"""
2651 if fname.endswith('.ipynb'):
2651 if fname.endswith('.ipynb'):
2652 from IPython.nbformat import current
2652 from IPython.nbformat import read
2653 with open(fname) as f:
2653 with io_open(fname) as f:
2654 nb = current.read(f, 'json')
2654 nb = read(f, as_version=4)
2655 if not nb.worksheets:
2655 if not nb.cells:
2656 return
2656 return
2657 for cell in nb.worksheets[0].cells:
2657 for cell in nb.cells:
2658 if cell.cell_type == 'code':
2658 if cell.cell_type == 'code':
2659 yield cell.input
2659 yield cell.source
2660 else:
2660 else:
2661 with open(fname) as f:
2661 with open(fname) as f:
2662 yield f.read()
2662 yield f.read()
@@ -1,25 +1,12 b''
1 """Implementation of basic magic functions.
1 """Implementation of basic magic functions."""
2 """
2
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2012 The IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14 from __future__ import print_function
3 from __future__ import print_function
15
4
16 # Stdlib
17 import io
5 import io
18 import json
6 import json
19 import sys
7 import sys
20 from pprint import pformat
8 from pprint import pformat
21
9
22 # Our own packages
23 from IPython.core import magic_arguments, page
10 from IPython.core import magic_arguments, page
24 from IPython.core.error import UsageError
11 from IPython.core.error import UsageError
25 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
12 from IPython.core.magic import Magics, magics_class, line_magic, magic_escapes
@@ -30,9 +17,6 b' from IPython.utils.path import unquote_filename'
30 from IPython.utils.py3compat import unicode_type
17 from IPython.utils.py3compat import unicode_type
31 from IPython.utils.warn import warn, error
18 from IPython.utils.warn import warn, error
32
19
33 #-----------------------------------------------------------------------------
34 # Magics class implementation
35 #-----------------------------------------------------------------------------
36
20
37 class MagicsDisplay(object):
21 class MagicsDisplay(object):
38 def __init__(self, magics_manager):
22 def __init__(self, magics_manager):
@@ -599,13 +583,6 b' Defaulting color scheme to \'NoColor\'"""'
599 'file extension will write the notebook as a Python script'
583 'file extension will write the notebook as a Python script'
600 )
584 )
601 @magic_arguments.argument(
585 @magic_arguments.argument(
602 '-f', '--format',
603 help='Convert an existing IPython notebook to a new format. This option '
604 'specifies the new format and can have the values: json, py. '
605 'The target filename is chosen automatically based on the new '
606 'format. The filename argument gives the name of the source file.'
607 )
608 @magic_arguments.argument(
609 'filename', type=unicode_type,
586 'filename', type=unicode_type,
610 help='Notebook name or filename'
587 help='Notebook name or filename'
611 )
588 )
@@ -613,41 +590,22 b' Defaulting color scheme to \'NoColor\'"""'
613 def notebook(self, s):
590 def notebook(self, s):
614 """Export and convert IPython notebooks.
591 """Export and convert IPython notebooks.
615
592
616 This function can export the current IPython history to a notebook file
593 This function can export the current IPython history to a notebook file.
617 or can convert an existing notebook file into a different format. For
594 For example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
618 example, to export the history to "foo.ipynb" do "%notebook -e foo.ipynb".
595 To export the history to "foo.py" do "%notebook -e foo.py".
619 To export the history to "foo.py" do "%notebook -e foo.py". To convert
620 "foo.ipynb" to "foo.json" do "%notebook -f json foo.ipynb". Possible
621 formats include (json/ipynb, py).
622 """
596 """
623 args = magic_arguments.parse_argstring(self.notebook, s)
597 args = magic_arguments.parse_argstring(self.notebook, s)
624
598
625 from IPython.nbformat import current
599 from IPython.nbformat import write, v4
626 args.filename = unquote_filename(args.filename)
600 args.filename = unquote_filename(args.filename)
627 if args.export:
601 if args.export:
628 fname, name, format = current.parse_filename(args.filename)
629 cells = []
602 cells = []
630 hist = list(self.shell.history_manager.get_range())
603 hist = list(self.shell.history_manager.get_range())
631 for session, prompt_number, input in hist[:-1]:
604 for session, execution_count, input in hist[:-1]:
632 cells.append(current.new_code_cell(prompt_number=prompt_number,
605 cells.append(v4.new_code_cell(
633 input=input))
606 execution_count=execution_count,
634 worksheet = current.new_worksheet(cells=cells)
607 source=source
635 nb = current.new_notebook(name=name,worksheets=[worksheet])
608 ))
636 with io.open(fname, 'w', encoding='utf-8') as f:
609 nb = v4.new_notebook(cells=cells)
637 current.write(nb, f, format);
610 with io.open(args.filename, 'w', encoding='utf-8') as f:
638 elif args.format is not None:
611 write(nb, f, version=4)
639 old_fname, old_name, old_format = current.parse_filename(args.filename)
640 new_format = args.format
641 if new_format == u'xml':
642 raise ValueError('Notebooks cannot be written as xml.')
643 elif new_format == u'ipynb' or new_format == u'json':
644 new_fname = old_name + u'.ipynb'
645 new_format = u'json'
646 elif new_format == u'py':
647 new_fname = old_name + u'.py'
648 else:
649 raise ValueError('Invalid notebook format: %s' % new_format)
650 with io.open(old_fname, 'r', encoding='utf-8') as f:
651 nb = current.read(f, old_format)
652 with io.open(new_fname, 'w', encoding='utf-8') as f:
653 current.write(nb, f, new_format)
@@ -5,10 +5,6 b' Needs to be run by nose (to make ipython session available).'
5 """
5 """
6 from __future__ import absolute_import
6 from __future__ import absolute_import
7
7
8 #-----------------------------------------------------------------------------
9 # Imports
10 #-----------------------------------------------------------------------------
11
12 import io
8 import io
13 import os
9 import os
14 import sys
10 import sys
@@ -40,9 +36,6 b' if py3compat.PY3:'
40 else:
36 else:
41 from StringIO import StringIO
37 from StringIO import StringIO
42
38
43 #-----------------------------------------------------------------------------
44 # Test functions begin
45 #-----------------------------------------------------------------------------
46
39
47 @magic.magics_class
40 @magic.magics_class
48 class DummyMagics(magic.Magics): pass
41 class DummyMagics(magic.Magics): pass
@@ -624,7 +617,7 b' def test_extension():'
624
617
625
618
626 # The nose skip decorator doesn't work on classes, so this uses unittest's skipIf
619 # The nose skip decorator doesn't work on classes, so this uses unittest's skipIf
627 @skipIf(dec.module_not_available('IPython.nbformat.current'), 'nbformat not importable')
620 @skipIf(dec.module_not_available('IPython.nbformat'), 'nbformat not importable')
628 class NotebookExportMagicTests(TestCase):
621 class NotebookExportMagicTests(TestCase):
629 def test_notebook_export_json(self):
622 def test_notebook_export_json(self):
630 with TemporaryDirectory() as td:
623 with TemporaryDirectory() as td:
@@ -632,35 +625,6 b' class NotebookExportMagicTests(TestCase):'
632 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
625 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
633 _ip.magic("notebook -e %s" % outfile)
626 _ip.magic("notebook -e %s" % outfile)
634
627
635 def test_notebook_export_py(self):
636 with TemporaryDirectory() as td:
637 outfile = os.path.join(td, "nb.py")
638 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
639 _ip.magic("notebook -e %s" % outfile)
640
641 def test_notebook_reformat_py(self):
642 from IPython.nbformat.v3.tests.nbexamples import nb0
643 from IPython.nbformat import current
644 with TemporaryDirectory() as td:
645 infile = os.path.join(td, "nb.ipynb")
646 with io.open(infile, 'w', encoding='utf-8') as f:
647 current.write(nb0, f, 'json')
648
649 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
650 _ip.magic("notebook -f py %s" % infile)
651
652 def test_notebook_reformat_json(self):
653 from IPython.nbformat.v3.tests.nbexamples import nb0
654 from IPython.nbformat import current
655 with TemporaryDirectory() as td:
656 infile = os.path.join(td, "nb.py")
657 with io.open(infile, 'w', encoding='utf-8') as f:
658 current.write(nb0, f, 'py')
659
660 _ip.ex(py3compat.u_format(u"u = {u}'héllo'"))
661 _ip.magic("notebook -f ipynb %s" % infile)
662 _ip.magic("notebook -f json %s" % infile)
663
664
628
665 def test_env():
629 def test_env():
666 env = _ip.magic("env")
630 env = _ip.magic("env")
@@ -7,11 +7,12 b' will be kept in this separate file. This makes it easier to aggregate in one'
7 place the tricks needed to handle it; most other magics are much easier to test
7 place the tricks needed to handle it; most other magics are much easier to test
8 and we do so in a common test_magic file.
8 and we do so in a common test_magic file.
9 """
9 """
10
11 # Copyright (c) IPython Development Team.
12 # Distributed under the terms of the Modified BSD License.
13
10 from __future__ import absolute_import
14 from __future__ import absolute_import
11
15
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
16
16 import functools
17 import functools
17 import os
18 import os
@@ -32,9 +33,6 b' from IPython.utils.io import capture_output'
32 from IPython.utils.tempdir import TemporaryDirectory
33 from IPython.utils.tempdir import TemporaryDirectory
33 from IPython.core import debugger
34 from IPython.core import debugger
34
35
35 #-----------------------------------------------------------------------------
36 # Test functions begin
37 #-----------------------------------------------------------------------------
38
36
39 def doctest_refbug():
37 def doctest_refbug():
40 """Very nasty problem with references held by multiple runs of a script.
38 """Very nasty problem with references held by multiple runs of a script.
@@ -372,19 +370,17 b' tclass.py: deleting object: C-third'
372 with tt.AssertNotPrints('SystemExit'):
370 with tt.AssertNotPrints('SystemExit'):
373 _ip.magic('run -e %s' % self.fname)
371 _ip.magic('run -e %s' % self.fname)
374
372
375 @dec.skip_without('IPython.nbformat.current') # Requires jsonschema
373 @dec.skip_without('IPython.nbformat') # Requires jsonschema
376 def test_run_nb(self):
374 def test_run_nb(self):
377 """Test %run notebook.ipynb"""
375 """Test %run notebook.ipynb"""
378 from IPython.nbformat import current
376 from IPython.nbformat import v4, writes
379 nb = current.new_notebook(
377 nb = v4.new_notebook(
380 worksheets=[
378 cells=[
381 current.new_worksheet(cells=[
379 v4.new_markdown_cell("The Ultimate Question of Everything"),
382 current.new_text_cell("The Ultimate Question of Everything"),
380 v4.new_code_cell("answer=42")
383 current.new_code_cell("answer=42")
384 ])
385 ]
381 ]
386 )
382 )
387 src = current.writes(nb, 'json')
383 src = writes(nb, version=4)
388 self.mktmp(src, ext='.ipynb')
384 self.mktmp(src, ext='.ipynb')
389
385
390 _ip.magic("run %s" % self.fname)
386 _ip.magic("run %s" % self.fname)
@@ -13,7 +13,7 b' from ..base.handlers import ('
13 IPythonHandler, FilesRedirectHandler,
13 IPythonHandler, FilesRedirectHandler,
14 notebook_path_regex, path_regex,
14 notebook_path_regex, path_regex,
15 )
15 )
16 from IPython.nbformat.current import to_notebook_json
16 from IPython.nbformat import from_dict
17
17
18 from IPython.utils.py3compat import cast_bytes
18 from IPython.utils.py3compat import cast_bytes
19
19
@@ -114,14 +114,15 b' class NbconvertPostHandler(IPythonHandler):'
114 exporter = get_exporter(format, config=self.config)
114 exporter = get_exporter(format, config=self.config)
115
115
116 model = self.get_json_body()
116 model = self.get_json_body()
117 nbnode = to_notebook_json(model['content'])
117 name = model.get('name', 'notebook.ipynb')
118 nbnode = from_dict(model['content'])
118
119
119 try:
120 try:
120 output, resources = exporter.from_notebook_node(nbnode)
121 output, resources = exporter.from_notebook_node(nbnode)
121 except Exception as e:
122 except Exception as e:
122 raise web.HTTPError(500, "nbconvert failed: %s" % e)
123 raise web.HTTPError(500, "nbconvert failed: %s" % e)
123
124
124 if respond_zip(self, nbnode.metadata.name, output, resources):
125 if respond_zip(self, name, output, resources):
125 return
126 return
126
127
127 # MIME type
128 # MIME type
@@ -10,9 +10,10 b' import requests'
10
10
11 from IPython.html.utils import url_path_join
11 from IPython.html.utils import url_path_join
12 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
12 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
13 from IPython.nbformat.current import (new_notebook, write, new_worksheet,
13 from IPython.nbformat import write
14 new_heading_cell, new_code_cell,
14 from IPython.nbformat.v4 import (
15 new_output)
15 new_notebook, new_markdown_cell, new_code_cell, new_output,
16 )
16
17
17 from IPython.testing.decorators import onlyif_cmds_exist
18 from IPython.testing.decorators import onlyif_cmds_exist
18
19
@@ -43,7 +44,8 b' class NbconvertAPI(object):'
43
44
44 png_green_pixel = base64.encodestring(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00'
45 png_green_pixel = base64.encodestring(b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00'
45 b'\x00\x00\x01\x00\x00x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDAT'
46 b'\x00\x00\x01\x00\x00x00\x01\x08\x02\x00\x00\x00\x90wS\xde\x00\x00\x00\x0cIDAT'
46 b'\x08\xd7c\x90\xfb\xcf\x00\x00\x02\\\x01\x1e.~d\x87\x00\x00\x00\x00IEND\xaeB`\x82')
47 b'\x08\xd7c\x90\xfb\xcf\x00\x00\x02\\\x01\x1e.~d\x87\x00\x00\x00\x00IEND\xaeB`\x82'
48 ).decode('ascii')
47
49
48 class APITest(NotebookTestBase):
50 class APITest(NotebookTestBase):
49 def setUp(self):
51 def setUp(self):
@@ -52,19 +54,20 b' class APITest(NotebookTestBase):'
52 if not os.path.isdir(pjoin(nbdir, 'foo')):
54 if not os.path.isdir(pjoin(nbdir, 'foo')):
53 os.mkdir(pjoin(nbdir, 'foo'))
55 os.mkdir(pjoin(nbdir, 'foo'))
54
56
55 nb = new_notebook(name='testnb')
57 nb = new_notebook()
56
58
57 ws = new_worksheet()
59 nb.cells.append(new_markdown_cell(u'Created by test ³'))
58 nb.worksheets = [ws]
60 cc1 = new_code_cell(source=u'print(2*6)')
59 ws.cells.append(new_heading_cell(u'Created by test ³'))
61 cc1.outputs.append(new_output(output_type="stream", text=u'12'))
60 cc1 = new_code_cell(input=u'print(2*6)')
62 cc1.outputs.append(new_output(output_type="execute_result",
61 cc1.outputs.append(new_output(output_text=u'12', output_type='stream'))
63 data={'image/png' : png_green_pixel},
62 cc1.outputs.append(new_output(output_png=png_green_pixel, output_type='pyout'))
64 execution_count=1,
63 ws.cells.append(cc1)
65 ))
66 nb.cells.append(cc1)
64
67
65 with io.open(pjoin(nbdir, 'foo', 'testnb.ipynb'), 'w',
68 with io.open(pjoin(nbdir, 'foo', 'testnb.ipynb'), 'w',
66 encoding='utf-8') as f:
69 encoding='utf-8') as f:
67 write(nb, f, format='ipynb')
70 write(nb, f, version=4)
68
71
69 self.nbconvert_api = NbconvertAPI(self.base_url())
72 self.nbconvert_api = NbconvertAPI(self.base_url())
70
73
@@ -12,7 +12,7 b' import shutil'
12 from tornado import web
12 from tornado import web
13
13
14 from .manager import ContentsManager
14 from .manager import ContentsManager
15 from IPython.nbformat import current
15 from IPython import nbformat
16 from IPython.utils.io import atomic_writing
16 from IPython.utils.io import atomic_writing
17 from IPython.utils.path import ensure_dir_exists
17 from IPython.utils.path import ensure_dir_exists
18 from IPython.utils.traitlets import Unicode, Bool, TraitError
18 from IPython.utils.traitlets import Unicode, Bool, TraitError
@@ -253,9 +253,9 b' class FileContentsManager(ContentsManager):'
253 os_path = self._get_os_path(name, path)
253 os_path = self._get_os_path(name, path)
254 with io.open(os_path, 'r', encoding='utf-8') as f:
254 with io.open(os_path, 'r', encoding='utf-8') as f:
255 try:
255 try:
256 nb = current.read(f, u'json')
256 nb = nbformat.read(f, as_version=4)
257 except Exception as e:
257 except Exception as e:
258 raise web.HTTPError(400, u"Unreadable Notebook: %s %s" % (os_path, e))
258 raise web.HTTPError(400, u"Unreadable Notebook: %s %r" % (os_path, e))
259 self.mark_trusted_cells(nb, name, path)
259 self.mark_trusted_cells(nb, name, path)
260 model['content'] = nb
260 model['content'] = nb
261 model['format'] = 'json'
261 model['format'] = 'json'
@@ -295,7 +295,7 b' class FileContentsManager(ContentsManager):'
295 def _save_notebook(self, os_path, model, name='', path=''):
295 def _save_notebook(self, os_path, model, name='', path=''):
296 """save a notebook file"""
296 """save a notebook file"""
297 # Save the notebook file
297 # Save the notebook file
298 nb = current.to_notebook_json(model['content'])
298 nb = nbformat.from_dict(model['content'])
299
299
300 self.check_and_sign(nb, name, path)
300 self.check_and_sign(nb, name, path)
301
301
@@ -303,7 +303,7 b' class FileContentsManager(ContentsManager):'
303 nb['metadata']['name'] = u''
303 nb['metadata']['name'] = u''
304
304
305 with atomic_writing(os_path, encoding='utf-8') as f:
305 with atomic_writing(os_path, encoding='utf-8') as f:
306 current.write(nb, f, version=nb.nbformat)
306 nbformat.write(nb, f, version=nbformat.NO_CONVERT)
307
307
308 def _save_file(self, os_path, model, name='', path=''):
308 def _save_file(self, os_path, model, name='', path=''):
309 """save a non-notebook file"""
309 """save a non-notebook file"""
@@ -522,7 +522,7 b' class FileContentsManager(ContentsManager):'
522 # ensure notebook is readable (never restore from an unreadable notebook)
522 # ensure notebook is readable (never restore from an unreadable notebook)
523 if cp_path.endswith('.ipynb'):
523 if cp_path.endswith('.ipynb'):
524 with io.open(cp_path, 'r', encoding='utf-8') as f:
524 with io.open(cp_path, 'r', encoding='utf-8') as f:
525 current.read(f, u'json')
525 nbformat.read(f, as_version=4)
526 self._copy(cp_path, nb_path)
526 self._copy(cp_path, nb_path)
527 self.log.debug("copying %s -> %s", cp_path, nb_path)
527 self.log.debug("copying %s -> %s", cp_path, nb_path)
528
528
@@ -11,7 +11,8 b' import os'
11 from tornado.web import HTTPError
11 from tornado.web import HTTPError
12
12
13 from IPython.config.configurable import LoggingConfigurable
13 from IPython.config.configurable import LoggingConfigurable
14 from IPython.nbformat import current, sign
14 from IPython.nbformat import sign, validate, ValidationError
15 from IPython.nbformat.v4 import new_notebook
15 from IPython.utils.traitlets import Instance, Unicode, List
16 from IPython.utils.traitlets import Instance, Unicode, List
16
17
17
18
@@ -220,8 +221,8 b' class ContentsManager(LoggingConfigurable):'
220 def validate_notebook_model(self, model):
221 def validate_notebook_model(self, model):
221 """Add failed-validation message to model"""
222 """Add failed-validation message to model"""
222 try:
223 try:
223 current.validate(model['content'])
224 validate(model['content'])
224 except current.ValidationError as e:
225 except ValidationError as e:
225 model['message'] = 'Notebook Validation failed: {}:\n{}'.format(
226 model['message'] = 'Notebook Validation failed: {}:\n{}'.format(
226 e.message, json.dumps(e.instance, indent=1, default=lambda obj: '<UNKNOWN>'),
227 e.message, json.dumps(e.instance, indent=1, default=lambda obj: '<UNKNOWN>'),
227 )
228 )
@@ -234,8 +235,7 b' class ContentsManager(LoggingConfigurable):'
234 model = {}
235 model = {}
235 if 'content' not in model and model.get('type', None) != 'directory':
236 if 'content' not in model and model.get('type', None) != 'directory':
236 if ext == '.ipynb':
237 if ext == '.ipynb':
237 metadata = current.new_metadata(name=u'')
238 model['content'] = new_notebook()
238 model['content'] = current.new_notebook(metadata=metadata)
239 model['type'] = 'notebook'
239 model['type'] = 'notebook'
240 model['format'] = 'json'
240 model['format'] = 'json'
241 else:
241 else:
@@ -309,14 +309,12 b' class ContentsManager(LoggingConfigurable):'
309 Parameters
309 Parameters
310 ----------
310 ----------
311 nb : dict
311 nb : dict
312 The notebook object (in nbformat.current format)
312 The notebook dict
313 name : string
313 name : string
314 The filename of the notebook (for logging)
314 The filename of the notebook (for logging)
315 path : string
315 path : string
316 The notebook's directory (for logging)
316 The notebook's directory (for logging)
317 """
317 """
318 if nb['nbformat'] != current.nbformat:
319 return
320 if self.notary.check_cells(nb):
318 if self.notary.check_cells(nb):
321 self.notary.sign(nb)
319 self.notary.sign(nb)
322 else:
320 else:
@@ -330,7 +328,7 b' class ContentsManager(LoggingConfigurable):'
330 Parameters
328 Parameters
331 ----------
329 ----------
332 nb : dict
330 nb : dict
333 The notebook object (in nbformat.current format)
331 The notebook object (in current nbformat)
334 name : string
332 name : string
335 The filename of the notebook (for logging)
333 The filename of the notebook (for logging)
336 path : string
334 path : string
@@ -14,9 +14,10 b' import requests'
14
14
15 from IPython.html.utils import url_path_join, url_escape
15 from IPython.html.utils import url_path_join, url_escape
16 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
16 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
17 from IPython.nbformat import current
17 from IPython.nbformat import read, write, from_dict
18 from IPython.nbformat.current import (new_notebook, write, read, new_worksheet,
18 from IPython.nbformat.v4 import (
19 new_heading_cell, to_notebook_json)
19 new_notebook, new_markdown_cell,
20 )
20 from IPython.nbformat import v2
21 from IPython.nbformat import v2
21 from IPython.utils import py3compat
22 from IPython.utils import py3compat
22 from IPython.utils.data import uniq_stable
23 from IPython.utils.data import uniq_stable
@@ -142,8 +143,8 b' class APITest(NotebookTestBase):'
142 # create a notebook
143 # create a notebook
143 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w',
144 with io.open(pjoin(nbdir, d, '%s.ipynb' % name), 'w',
144 encoding='utf-8') as f:
145 encoding='utf-8') as f:
145 nb = new_notebook(name=name)
146 nb = new_notebook()
146 write(nb, f, format='ipynb')
147 write(nb, f, version=4)
147
148
148 # create a text file
149 # create a text file
149 with io.open(pjoin(nbdir, d, '%s.txt' % name), 'w',
150 with io.open(pjoin(nbdir, d, '%s.txt' % name), 'w',
@@ -286,14 +287,14 b' class APITest(NotebookTestBase):'
286 self.assertEqual(model['content'], '')
287 self.assertEqual(model['content'], '')
287
288
288 def test_upload_untitled(self):
289 def test_upload_untitled(self):
289 nb = new_notebook(name='Upload test')
290 nb = new_notebook()
290 nbmodel = {'content': nb, 'type': 'notebook'}
291 nbmodel = {'content': nb, 'type': 'notebook'}
291 resp = self.api.upload_untitled(path=u'Ã¥ b',
292 resp = self.api.upload_untitled(path=u'Ã¥ b',
292 body=json.dumps(nbmodel))
293 body=json.dumps(nbmodel))
293 self._check_created(resp, 'Untitled0.ipynb', u'Ã¥ b')
294 self._check_created(resp, 'Untitled0.ipynb', u'Ã¥ b')
294
295
295 def test_upload(self):
296 def test_upload(self):
296 nb = new_notebook(name=u'ignored')
297 nb = new_notebook()
297 nbmodel = {'content': nb, 'type': 'notebook'}
298 nbmodel = {'content': nb, 'type': 'notebook'}
298 resp = self.api.upload(u'Upload tést.ipynb', path=u'å b',
299 resp = self.api.upload(u'Upload tést.ipynb', path=u'å b',
299 body=json.dumps(nbmodel))
300 body=json.dumps(nbmodel))
@@ -354,8 +355,7 b' class APITest(NotebookTestBase):'
354 self._check_created(resp, u'Upload tést.ipynb', u'å b')
355 self._check_created(resp, u'Upload tést.ipynb', u'å b')
355 resp = self.api.read(u'Upload tést.ipynb', u'å b')
356 resp = self.api.read(u'Upload tést.ipynb', u'å b')
356 data = resp.json()
357 data = resp.json()
357 self.assertEqual(data['content']['nbformat'], current.nbformat)
358 self.assertEqual(data['content']['nbformat'], 4)
358 self.assertEqual(data['content']['orig_nbformat'], 2)
359
359
360 def test_copy_untitled(self):
360 def test_copy_untitled(self):
361 resp = self.api.copy_untitled(u'ç d.ipynb', path=u'å b')
361 resp = self.api.copy_untitled(u'ç d.ipynb', path=u'å b')
@@ -415,22 +415,20 b' class APITest(NotebookTestBase):'
415 def test_save(self):
415 def test_save(self):
416 resp = self.api.read('a.ipynb', 'foo')
416 resp = self.api.read('a.ipynb', 'foo')
417 nbcontent = json.loads(resp.text)['content']
417 nbcontent = json.loads(resp.text)['content']
418 nb = to_notebook_json(nbcontent)
418 nb = from_dict(nbcontent)
419 ws = new_worksheet()
419 nb.cells.append(new_markdown_cell(u'Created by test ³'))
420 nb.worksheets = [ws]
421 ws.cells.append(new_heading_cell(u'Created by test ³'))
422
420
423 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'}
421 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'}
424 resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
422 resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
425
423
426 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
424 nbfile = pjoin(self.notebook_dir.name, 'foo', 'a.ipynb')
427 with io.open(nbfile, 'r', encoding='utf-8') as f:
425 with io.open(nbfile, 'r', encoding='utf-8') as f:
428 newnb = read(f, format='ipynb')
426 newnb = read(f, as_version=4)
429 self.assertEqual(newnb.worksheets[0].cells[0].source,
427 self.assertEqual(newnb.cells[0].source,
430 u'Created by test ³')
428 u'Created by test ³')
431 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
429 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
432 newnb = to_notebook_json(nbcontent)
430 newnb = from_dict(nbcontent)
433 self.assertEqual(newnb.worksheets[0].cells[0].source,
431 self.assertEqual(newnb.cells[0].source,
434 u'Created by test ³')
432 u'Created by test ³')
435
433
436 # Save and rename
434 # Save and rename
@@ -454,11 +452,9 b' class APITest(NotebookTestBase):'
454
452
455 # Modify it
453 # Modify it
456 nbcontent = json.loads(resp.text)['content']
454 nbcontent = json.loads(resp.text)['content']
457 nb = to_notebook_json(nbcontent)
455 nb = from_dict(nbcontent)
458 ws = new_worksheet()
456 hcell = new_markdown_cell('Created by test')
459 nb.worksheets = [ws]
457 nb.cells.append(hcell)
460 hcell = new_heading_cell('Created by test')
461 ws.cells.append(hcell)
462 # Save
458 # Save
463 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'}
459 nbmodel= {'name': 'a.ipynb', 'path':'foo', 'content': nb, 'type': 'notebook'}
464 resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
460 resp = self.api.save('a.ipynb', path='foo', body=json.dumps(nbmodel))
@@ -468,15 +464,15 b' class APITest(NotebookTestBase):'
468 self.assertEqual(cps, [cp1])
464 self.assertEqual(cps, [cp1])
469
465
470 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
466 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
471 nb = to_notebook_json(nbcontent)
467 nb = from_dict(nbcontent)
472 self.assertEqual(nb.worksheets[0].cells[0].source, 'Created by test')
468 self.assertEqual(nb.cells[0].source, 'Created by test')
473
469
474 # Restore cp1
470 # Restore cp1
475 r = self.api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
471 r = self.api.restore_checkpoint('a.ipynb', 'foo', cp1['id'])
476 self.assertEqual(r.status_code, 204)
472 self.assertEqual(r.status_code, 204)
477 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
473 nbcontent = self.api.read('a.ipynb', 'foo').json()['content']
478 nb = to_notebook_json(nbcontent)
474 nb = from_dict(nbcontent)
479 self.assertEqual(nb.worksheets, [])
475 self.assertEqual(nb.cells, [])
480
476
481 # Delete cp1
477 # Delete cp1
482 r = self.api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
478 r = self.api.delete_checkpoint('a.ipynb', 'foo', cp1['id'])
@@ -9,7 +9,7 b' from tornado.web import HTTPError'
9 from unittest import TestCase
9 from unittest import TestCase
10 from tempfile import NamedTemporaryFile
10 from tempfile import NamedTemporaryFile
11
11
12 from IPython.nbformat import current
12 from IPython.nbformat import v4 as nbformat
13
13
14 from IPython.utils.tempdir import TemporaryDirectory
14 from IPython.utils.tempdir import TemporaryDirectory
15 from IPython.utils.traitlets import TraitError
15 from IPython.utils.traitlets import TraitError
@@ -95,11 +95,9 b' class TestContentsManager(TestCase):'
95 return os_path
95 return os_path
96
96
97 def add_code_cell(self, nb):
97 def add_code_cell(self, nb):
98 output = current.new_output("display_data", output_javascript="alert('hi');")
98 output = nbformat.new_output("display_data", {'application/javascript': "alert('hi');"})
99 cell = current.new_code_cell("print('hi')", outputs=[output])
99 cell = nbformat.new_code_cell("print('hi')", outputs=[output])
100 if not nb.worksheets:
100 nb.cells.append(cell)
101 nb.worksheets.append(current.new_worksheet())
102 nb.worksheets[0].cells.append(cell)
103
101
104 def new_notebook(self):
102 def new_notebook(self):
105 cm = self.contents_manager
103 cm = self.contents_manager
@@ -309,13 +307,13 b' class TestContentsManager(TestCase):'
309 nb, name, path = self.new_notebook()
307 nb, name, path = self.new_notebook()
310
308
311 cm.mark_trusted_cells(nb, name, path)
309 cm.mark_trusted_cells(nb, name, path)
312 for cell in nb.worksheets[0].cells:
310 for cell in nb.cells:
313 if cell.cell_type == 'code':
311 if cell.cell_type == 'code':
314 assert not cell.metadata.trusted
312 assert not cell.metadata.trusted
315
313
316 cm.trust_notebook(name, path)
314 cm.trust_notebook(name, path)
317 nb = cm.get_model(name, path)['content']
315 nb = cm.get_model(name, path)['content']
318 for cell in nb.worksheets[0].cells:
316 for cell in nb.cells:
319 if cell.cell_type == 'code':
317 if cell.cell_type == 'code':
320 assert cell.metadata.trusted
318 assert cell.metadata.trusted
321
319
@@ -11,7 +11,8 b' pjoin = os.path.join'
11
11
12 from IPython.html.utils import url_path_join
12 from IPython.html.utils import url_path_join
13 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
13 from IPython.html.tests.launchnotebook import NotebookTestBase, assert_http_error
14 from IPython.nbformat.current import new_notebook, write
14 from IPython.nbformat.v4 import new_notebook
15 from IPython.nbformat import write
15
16
16 class SessionAPI(object):
17 class SessionAPI(object):
17 """Wrapper for notebook API calls."""
18 """Wrapper for notebook API calls."""
@@ -62,8 +63,8 b' class SessionAPITest(NotebookTestBase):'
62
63
63 with io.open(pjoin(nbdir, 'foo', 'nb1.ipynb'), 'w',
64 with io.open(pjoin(nbdir, 'foo', 'nb1.ipynb'), 'w',
64 encoding='utf-8') as f:
65 encoding='utf-8') as f:
65 nb = new_notebook(name='nb1')
66 nb = new_notebook()
66 write(nb, f, format='ipynb')
67 write(nb, f, version=4)
67
68
68 self.sess_api = SessionAPI(self.base_url())
69 self.sess_api = SessionAPI(self.base_url())
69
70
@@ -382,13 +382,11 b' define(['
382
382
383
383
384 CodeCell.prototype.collapse_output = function () {
384 CodeCell.prototype.collapse_output = function () {
385 this.collapsed = true;
386 this.output_area.collapse();
385 this.output_area.collapse();
387 };
386 };
388
387
389
388
390 CodeCell.prototype.expand_output = function () {
389 CodeCell.prototype.expand_output = function () {
391 this.collapsed = false;
392 this.output_area.expand();
390 this.output_area.expand();
393 this.output_area.unscroll_area();
391 this.output_area.unscroll_area();
394 };
392 };
@@ -399,7 +397,6 b' define(['
399 };
397 };
400
398
401 CodeCell.prototype.toggle_output = function () {
399 CodeCell.prototype.toggle_output = function () {
402 this.collapsed = Boolean(1 - this.collapsed);
403 this.output_area.toggle_output();
400 this.output_area.toggle_output();
404 };
401 };
405
402
@@ -467,22 +464,18 b' define(['
467 CodeCell.prototype.fromJSON = function (data) {
464 CodeCell.prototype.fromJSON = function (data) {
468 Cell.prototype.fromJSON.apply(this, arguments);
465 Cell.prototype.fromJSON.apply(this, arguments);
469 if (data.cell_type === 'code') {
466 if (data.cell_type === 'code') {
470 if (data.input !== undefined) {
467 if (data.source !== undefined) {
471 this.set_text(data.input);
468 this.set_text(data.source);
472 // make this value the starting point, so that we can only undo
469 // make this value the starting point, so that we can only undo
473 // to this state, instead of a blank cell
470 // to this state, instead of a blank cell
474 this.code_mirror.clearHistory();
471 this.code_mirror.clearHistory();
475 this.auto_highlight();
472 this.auto_highlight();
476 }
473 }
477 if (data.prompt_number !== undefined) {
474 this.set_input_prompt(data.execution_count);
478 this.set_input_prompt(data.prompt_number);
479 } else {
480 this.set_input_prompt();
481 }
482 this.output_area.trusted = data.metadata.trusted || false;
475 this.output_area.trusted = data.metadata.trusted || false;
483 this.output_area.fromJSON(data.outputs);
476 this.output_area.fromJSON(data.outputs);
484 if (data.collapsed !== undefined) {
477 if (data.metadata.collapsed !== undefined) {
485 if (data.collapsed) {
478 if (data.metadata.collapsed) {
486 this.collapse_output();
479 this.collapse_output();
487 } else {
480 } else {
488 this.expand_output();
481 this.expand_output();
@@ -494,16 +487,17 b' define(['
494
487
495 CodeCell.prototype.toJSON = function () {
488 CodeCell.prototype.toJSON = function () {
496 var data = Cell.prototype.toJSON.apply(this);
489 var data = Cell.prototype.toJSON.apply(this);
497 data.input = this.get_text();
490 data.source = this.get_text();
498 // is finite protect against undefined and '*' value
491 // is finite protect against undefined and '*' value
499 if (isFinite(this.input_prompt_number)) {
492 if (isFinite(this.input_prompt_number)) {
500 data.prompt_number = this.input_prompt_number;
493 data.execution_count = this.input_prompt_number;
494 } else {
495 data.execution_count = null;
501 }
496 }
502 var outputs = this.output_area.toJSON();
497 var outputs = this.output_area.toJSON();
503 data.outputs = outputs;
498 data.outputs = outputs;
504 data.language = 'python';
505 data.metadata.trusted = this.output_area.trusted;
499 data.metadata.trusted = this.output_area.trusted;
506 data.collapsed = this.output_area.collapsed;
500 data.metadata.collapsed = this.output_area.collapsed;
507 return data;
501 return data;
508 };
502 };
509
503
@@ -139,12 +139,6 b' define(['
139 .append($('<option/>').attr('value','code').text('Code'))
139 .append($('<option/>').attr('value','code').text('Code'))
140 .append($('<option/>').attr('value','markdown').text('Markdown'))
140 .append($('<option/>').attr('value','markdown').text('Markdown'))
141 .append($('<option/>').attr('value','raw').text('Raw NBConvert'))
141 .append($('<option/>').attr('value','raw').text('Raw NBConvert'))
142 .append($('<option/>').attr('value','heading1').text('Heading 1'))
143 .append($('<option/>').attr('value','heading2').text('Heading 2'))
144 .append($('<option/>').attr('value','heading3').text('Heading 3'))
145 .append($('<option/>').attr('value','heading4').text('Heading 4'))
146 .append($('<option/>').attr('value','heading5').text('Heading 5'))
147 .append($('<option/>').attr('value','heading6').text('Heading 6'))
148 );
142 );
149 };
143 };
150
144
@@ -190,24 +184,18 b' define(['
190
184
191 this.element.find('#cell_type').change(function () {
185 this.element.find('#cell_type').change(function () {
192 var cell_type = $(this).val();
186 var cell_type = $(this).val();
193 if (cell_type === 'code') {
187 switch (cell_type) {
188 case 'code':
194 that.notebook.to_code();
189 that.notebook.to_code();
195 } else if (cell_type === 'markdown') {
190 break;
191 case 'markdown':
196 that.notebook.to_markdown();
192 that.notebook.to_markdown();
197 } else if (cell_type === 'raw') {
193 break;
194 case 'raw':
198 that.notebook.to_raw();
195 that.notebook.to_raw();
199 } else if (cell_type === 'heading1') {
196 break;
200 that.notebook.to_heading(undefined, 1);
197 default:
201 } else if (cell_type === 'heading2') {
198 console.log("unrecognized cell type:", cell_type);
202 that.notebook.to_heading(undefined, 2);
203 } else if (cell_type === 'heading3') {
204 that.notebook.to_heading(undefined, 3);
205 } else if (cell_type === 'heading4') {
206 that.notebook.to_heading(undefined, 4);
207 } else if (cell_type === 'heading5') {
208 that.notebook.to_heading(undefined, 5);
209 } else if (cell_type === 'heading6') {
210 that.notebook.to_heading(undefined, 6);
211 }
199 }
212 });
200 });
213 this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
201 this.events.on('selected_cell_type_changed.Notebook', function (event, data) {
@@ -121,10 +121,8 b' define(['
121 this.autosave_timer = null;
121 this.autosave_timer = null;
122 // autosave *at most* every two minutes
122 // autosave *at most* every two minutes
123 this.minimum_autosave_interval = 120000;
123 this.minimum_autosave_interval = 120000;
124 // single worksheet for now
125 this.worksheet_metadata = {};
126 this.notebook_name_blacklist_re = /[\/\\:]/;
124 this.notebook_name_blacklist_re = /[\/\\:]/;
127 this.nbformat = 3; // Increment this when changing the nbformat
125 this.nbformat = 4; // Increment this when changing the nbformat
128 this.nbformat_minor = 0; // Increment this when changing the nbformat
126 this.nbformat_minor = 0; // Increment this when changing the nbformat
129 this.codemirror_mode = 'ipython';
127 this.codemirror_mode = 'ipython';
130 this.create_elements();
128 this.create_elements();
@@ -826,7 +824,7 b' define(['
826 * Index will be brought back into the accessible range [0,n]
824 * Index will be brought back into the accessible range [0,n]
827 *
825 *
828 * @method insert_cell_at_index
826 * @method insert_cell_at_index
829 * @param [type] {string} in ['code','markdown','heading'], defaults to 'code'
827 * @param [type] {string} in ['code','markdown', 'raw'], defaults to 'code'
830 * @param [index] {int} a valid index where to insert cell
828 * @param [index] {int} a valid index where to insert cell
831 *
829 *
832 * @return cell {cell|null} created cell or null
830 * @return cell {cell|null} created cell or null
@@ -862,15 +860,19 b' define(['
862 notebook: this,
860 notebook: this,
863 tooltip: this.tooltip,
861 tooltip: this.tooltip,
864 };
862 };
865 if (type === 'code') {
863 switch(type) {
864 case 'code':
866 cell = new codecell.CodeCell(this.kernel, cell_options);
865 cell = new codecell.CodeCell(this.kernel, cell_options);
867 cell.set_input_prompt();
866 cell.set_input_prompt();
868 } else if (type === 'markdown') {
867 break;
868 case 'markdown':
869 cell = new textcell.MarkdownCell(cell_options);
869 cell = new textcell.MarkdownCell(cell_options);
870 } else if (type === 'raw') {
870 break;
871 case 'raw':
871 cell = new textcell.RawCell(cell_options);
872 cell = new textcell.RawCell(cell_options);
872 } else if (type === 'heading') {
873 break;
873 cell = new textcell.HeadingCell(cell_options);
874 default:
875 console.log("invalid cell type: ", type);
874 }
876 }
875
877
876 if(this._insert_element_at_index(cell.element,index)) {
878 if(this._insert_element_at_index(cell.element,index)) {
@@ -1092,10 +1094,10 b' define(['
1092 if (this.is_valid_cell_index(i)) {
1094 if (this.is_valid_cell_index(i)) {
1093 var source_cell = this.get_cell(i);
1095 var source_cell = this.get_cell(i);
1094 var target_cell = null;
1096 var target_cell = null;
1095 if (source_cell instanceof textcell.HeadingCell) {
1097 if (source_cell instanceof textcell.MarkdownCell) {
1096 source_cell.set_level(level);
1098 source_cell.set_heading_level(level);
1097 } else {
1099 } else {
1098 target_cell = this.insert_cell_below('heading',i);
1100 target_cell = this.insert_cell_below('markdown',i);
1099 var text = source_cell.get_text();
1101 var text = source_cell.get_text();
1100 if (text === source_cell.placeholder) {
1102 if (text === source_cell.placeholder) {
1101 text = '';
1103 text = '';
@@ -1103,9 +1105,9 b' define(['
1103 //metadata
1105 //metadata
1104 target_cell.metadata = source_cell.metadata;
1106 target_cell.metadata = source_cell.metadata;
1105 // We must show the editor before setting its contents
1107 // We must show the editor before setting its contents
1106 target_cell.set_level(level);
1107 target_cell.unrender();
1108 target_cell.unrender();
1108 target_cell.set_text(text);
1109 target_cell.set_text(text);
1110 target_cell.set_heading_level(level);
1109 // make this value the starting point, so that we can only undo
1111 // make this value the starting point, so that we can only undo
1110 // to this state, instead of a blank cell
1112 // to this state, instead of a blank cell
1111 target_cell.code_mirror.clearHistory();
1113 target_cell.code_mirror.clearHistory();
@@ -1119,7 +1121,7 b' define(['
1119 }
1121 }
1120 this.set_dirty(true);
1122 this.set_dirty(true);
1121 this.events.trigger('selected_cell_type_changed.Notebook',
1123 this.events.trigger('selected_cell_type_changed.Notebook',
1122 {'cell_type':'heading',level:level}
1124 {'cell_type':'markdown',level:level}
1123 );
1125 );
1124 }
1126 }
1125 };
1127 };
@@ -1528,8 +1530,8 b' define(['
1528 }
1530 }
1529 this.codemirror_mode = newmode;
1531 this.codemirror_mode = newmode;
1530 codecell.CodeCell.options_default.cm_config.mode = newmode;
1532 codecell.CodeCell.options_default.cm_config.mode = newmode;
1531 modename = newmode.mode || newmode.name || newmode
1533 modename = newmode.mode || newmode.name || newmode;
1532
1534
1533 that = this;
1535 that = this;
1534 utils.requireCodeMirrorMode(modename, function () {
1536 utils.requireCodeMirrorMode(modename, function () {
1535 $.map(that.get_cells(), function(cell, i) {
1537 $.map(that.get_cells(), function(cell, i) {
@@ -1541,7 +1543,7 b' define(['
1541 cell.cm_config.mode = newmode;
1543 cell.cm_config.mode = newmode;
1542 }
1544 }
1543 });
1545 });
1544 })
1546 });
1545 };
1547 };
1546
1548
1547 // Session related things
1549 // Session related things
@@ -1785,8 +1787,6 b' define(['
1785 /**
1787 /**
1786 * Load a notebook from JSON (.ipynb).
1788 * Load a notebook from JSON (.ipynb).
1787 *
1789 *
1788 * This currently handles one worksheet: others are deleted.
1789 *
1790 * @method fromJSON
1790 * @method fromJSON
1791 * @param {Object} data JSON representation of a notebook
1791 * @param {Object} data JSON representation of a notebook
1792 */
1792 */
@@ -1818,50 +1818,22 b' define(['
1818 this.set_codemirror_mode(cm_mode);
1818 this.set_codemirror_mode(cm_mode);
1819 }
1819 }
1820
1820
1821 // Only handle 1 worksheet for now.
1821 var new_cells = content.cells;
1822 var worksheet = content.worksheets[0];
1822 ncells = new_cells.length;
1823 if (worksheet !== undefined) {
1823 var cell_data = null;
1824 if (worksheet.metadata) {
1824 var new_cell = null;
1825 this.worksheet_metadata = worksheet.metadata;
1825 for (i=0; i<ncells; i++) {
1826 }
1826 cell_data = new_cells[i];
1827 var new_cells = worksheet.cells;
1827 new_cell = this.insert_cell_at_index(cell_data.cell_type, i);
1828 ncells = new_cells.length;
1828 new_cell.fromJSON(cell_data);
1829 var cell_data = null;
1829 if (new_cell.cell_type == 'code' && !new_cell.output_area.trusted) {
1830 var new_cell = null;
1830 trusted = false;
1831 for (i=0; i<ncells; i++) {
1832 cell_data = new_cells[i];
1833 // VERSIONHACK: plaintext -> raw
1834 // handle never-released plaintext name for raw cells
1835 if (cell_data.cell_type === 'plaintext'){
1836 cell_data.cell_type = 'raw';
1837 }
1838
1839 new_cell = this.insert_cell_at_index(cell_data.cell_type, i);
1840 new_cell.fromJSON(cell_data);
1841 if (new_cell.cell_type == 'code' && !new_cell.output_area.trusted) {
1842 trusted = false;
1843 }
1844 }
1831 }
1845 }
1832 }
1846 if (trusted !== this.trusted) {
1833 if (trusted !== this.trusted) {
1847 this.trusted = trusted;
1834 this.trusted = trusted;
1848 this.events.trigger("trust_changed.Notebook", trusted);
1835 this.events.trigger("trust_changed.Notebook", trusted);
1849 }
1836 }
1850 if (content.worksheets.length > 1) {
1851 dialog.modal({
1852 notebook: this,
1853 keyboard_manager: this.keyboard_manager,
1854 title : "Multiple worksheets",
1855 body : "This notebook has " + data.worksheets.length + " worksheets, " +
1856 "but this version of IPython can only handle the first. " +
1857 "If you save this notebook, worksheets after the first will be lost.",
1858 buttons : {
1859 OK : {
1860 class : "btn-danger"
1861 }
1862 }
1863 });
1864 }
1865 };
1837 };
1866
1838
1867 /**
1839 /**
@@ -1871,6 +1843,10 b' define(['
1871 * @return {Object} A JSON-friendly representation of this notebook.
1843 * @return {Object} A JSON-friendly representation of this notebook.
1872 */
1844 */
1873 Notebook.prototype.toJSON = function () {
1845 Notebook.prototype.toJSON = function () {
1846 // remove the conversion indicator, which only belongs in-memory
1847 delete this.metadata.orig_nbformat;
1848 delete this.metadata.orig_nbformat_minor;
1849
1874 var cells = this.get_cells();
1850 var cells = this.get_cells();
1875 var ncells = cells.length;
1851 var ncells = cells.length;
1876 var cell_array = new Array(ncells);
1852 var cell_array = new Array(ncells);
@@ -1883,11 +1859,7 b' define(['
1883 cell_array[i] = cell.toJSON();
1859 cell_array[i] = cell.toJSON();
1884 }
1860 }
1885 var data = {
1861 var data = {
1886 // Only handle 1 worksheet for now.
1862 cells: cell_array,
1887 worksheets : [{
1888 cells: cell_array,
1889 metadata: this.worksheet_metadata
1890 }],
1891 metadata : this.metadata
1863 metadata : this.metadata
1892 };
1864 };
1893 if (trusted != this.trusted) {
1865 if (trusted != this.trusted) {
@@ -2337,10 +2309,13 b' define(['
2337 }
2309 }
2338 this.set_dirty(false);
2310 this.set_dirty(false);
2339 this.scroll_to_top();
2311 this.scroll_to_top();
2340 if (data.orig_nbformat !== undefined && data.nbformat !== data.orig_nbformat) {
2312 var nbmodel = data.content;
2313 var orig_nbformat = nbmodel.metadata.orig_nbformat;
2314 var orig_nbformat_minor = nbmodel.metadata.orig_nbformat_minor;
2315 if (orig_nbformat !== undefined && nbmodel.nbformat !== orig_nbformat) {
2341 var msg = "This notebook has been converted from an older " +
2316 var msg = "This notebook has been converted from an older " +
2342 "notebook format (v"+data.orig_nbformat+") to the current notebook " +
2317 "notebook format (v"+orig_nbformat+") to the current notebook " +
2343 "format (v"+data.nbformat+"). The next time you save this notebook, the " +
2318 "format (v"+nbmodel.nbformat+"). The next time you save this notebook, the " +
2344 "newer notebook format will be used and older versions of IPython " +
2319 "newer notebook format will be used and older versions of IPython " +
2345 "may not be able to read it. To keep the older version, close the " +
2320 "may not be able to read it. To keep the older version, close the " +
2346 "notebook without saving it.";
2321 "notebook without saving it.";
@@ -2355,10 +2330,10 b' define(['
2355 }
2330 }
2356 }
2331 }
2357 });
2332 });
2358 } else if (data.orig_nbformat_minor !== undefined && data.nbformat_minor !== data.orig_nbformat_minor) {
2333 } else if (orig_nbformat_minor !== undefined && nbmodel.nbformat_minor !== orig_nbformat_minor) {
2359 var that = this;
2334 var that = this;
2360 var orig_vs = 'v' + data.nbformat + '.' + data.orig_nbformat_minor;
2335 var orig_vs = 'v' + nbmodel.nbformat + '.' + orig_nbformat_minor;
2361 var this_vs = 'v' + data.nbformat + '.' + this.nbformat_minor;
2336 var this_vs = 'v' + nbmodel.nbformat + '.' + this.nbformat_minor;
2362 var msg = "This notebook is version " + orig_vs + ", but we only fully support up to " +
2337 var msg = "This notebook is version " + orig_vs + ", but we only fully support up to " +
2363 this_vs + ". You can still work with this notebook, but some features " +
2338 this_vs + ". You can still work with this notebook, but some features " +
2364 "introduced in later notebook versions may not be available.";
2339 "introduced in later notebook versions may not be available.";
@@ -2412,13 +2387,13 b' define(['
2412 Notebook.prototype.load_notebook_error = function (xhr, status, error) {
2387 Notebook.prototype.load_notebook_error = function (xhr, status, error) {
2413 this.events.trigger('notebook_load_failed.Notebook', [xhr, status, error]);
2388 this.events.trigger('notebook_load_failed.Notebook', [xhr, status, error]);
2414 utils.log_ajax_error(xhr, status, error);
2389 utils.log_ajax_error(xhr, status, error);
2415 var msg;
2390 var msg = $("<div>");
2416 if (xhr.status === 400) {
2391 if (xhr.status === 400) {
2417 msg = escape(utils.ajax_error_msg(xhr));
2392 msg.text(utils.ajax_error_msg(xhr));
2418 } else if (xhr.status === 500) {
2393 } else if (xhr.status === 500) {
2419 msg = "An unknown error occurred while loading this notebook. " +
2394 msg.text("An unknown error occurred while loading this notebook. " +
2420 "This version can load notebook formats " +
2395 "This version can load notebook formats " +
2421 "v" + this.nbformat + " or earlier. See the server log for details.";
2396 "v" + this.nbformat + " or earlier. See the server log for details.");
2422 }
2397 }
2423 dialog.modal({
2398 dialog.modal({
2424 notebook: this,
2399 notebook: this,
@@ -81,7 +81,7 b' define(['
81 *
81 *
82 */
82 */
83 OutputArea.prototype._should_scroll = function (lines) {
83 OutputArea.prototype._should_scroll = function (lines) {
84 if (lines <=0 ){ return }
84 if (lines <=0 ){ return; }
85 if (!lines) {
85 if (!lines) {
86 lines = 100;
86 lines = 100;
87 }
87 }
@@ -177,7 +177,7 b' define(['
177 OutputArea.prototype.scroll_if_long = function (lines) {
177 OutputArea.prototype.scroll_if_long = function (lines) {
178 var n = lines | OutputArea.minimum_scroll_threshold;
178 var n = lines | OutputArea.minimum_scroll_threshold;
179 if(n <= 0){
179 if(n <= 0){
180 return
180 return;
181 }
181 }
182
182
183 if (this._should_scroll(n)) {
183 if (this._should_scroll(n)) {
@@ -211,16 +211,16 b' define(['
211 var content = msg.content;
211 var content = msg.content;
212 if (msg_type === "stream") {
212 if (msg_type === "stream") {
213 json.text = content.text;
213 json.text = content.text;
214 json.stream = content.name;
214 json.name = content.name;
215 } else if (msg_type === "display_data") {
215 } else if (msg_type === "display_data") {
216 json = content.data;
216 json.data = content.data;
217 json.output_type = msg_type;
217 json.output_type = msg_type;
218 json.metadata = content.metadata;
218 json.metadata = content.metadata;
219 } else if (msg_type === "execute_result") {
219 } else if (msg_type === "execute_result") {
220 json = content.data;
220 json.data = content.data;
221 json.output_type = msg_type;
221 json.output_type = msg_type;
222 json.metadata = content.metadata;
222 json.metadata = content.metadata;
223 json.prompt_number = content.execution_count;
223 json.execution_count = content.execution_count;
224 } else if (msg_type === "error") {
224 } else if (msg_type === "error") {
225 json.ename = content.ename;
225 json.ename = content.ename;
226 json.evalue = content.evalue;
226 json.evalue = content.evalue;
@@ -233,16 +233,6 b' define(['
233 };
233 };
234
234
235
235
236 OutputArea.prototype.rename_keys = function (data, key_map) {
237 var remapped = {};
238 for (var key in data) {
239 var new_key = key_map[key] || key;
240 remapped[new_key] = data[key];
241 }
242 return remapped;
243 };
244
245
246 OutputArea.output_types = [
236 OutputArea.output_types = [
247 'application/javascript',
237 'application/javascript',
248 'text/html',
238 'text/html',
@@ -257,12 +247,14 b' define(['
257
247
258 OutputArea.prototype.validate_output = function (json) {
248 OutputArea.prototype.validate_output = function (json) {
259 // scrub invalid outputs
249 // scrub invalid outputs
260 // TODO: right now everything is a string, but JSON really shouldn't be.
250 var data = json.data;
261 // nbformat 4 will fix that.
262 $.map(OutputArea.output_types, function(key){
251 $.map(OutputArea.output_types, function(key){
263 if (json[key] !== undefined && typeof json[key] !== 'string') {
252 if (key !== 'application/json' &&
264 console.log("Invalid type for " + key, json[key]);
253 data[key] !== undefined &&
265 delete json[key];
254 typeof data[key] !== 'string'
255 ) {
256 console.log("Invalid type for " + key, data[key]);
257 delete data[key];
266 }
258 }
267 });
259 });
268 return json;
260 return json;
@@ -272,7 +264,9 b' define(['
272 this.expand();
264 this.expand();
273
265
274 // validate output data types
266 // validate output data types
275 json = this.validate_output(json);
267 if (json.data) {
268 json = this.validate_output(json);
269 }
276
270
277 // Clear the output if clear is queued.
271 // Clear the output if clear is queued.
278 var needs_height_reset = false;
272 var needs_height_reset = false;
@@ -376,12 +370,12 b' define(['
376 } else {
370 } else {
377 return subarea;
371 return subarea;
378 }
372 }
379 }
373 };
380
374
381
375
382 OutputArea.prototype._append_javascript_error = function (err, element) {
376 OutputArea.prototype._append_javascript_error = function (err, element) {
383 // display a message when a javascript error occurs in display output
377 // display a message when a javascript error occurs in display output
384 var msg = "Javascript error adding output!"
378 var msg = "Javascript error adding output!";
385 if ( element === undefined ) return;
379 if ( element === undefined ) return;
386 element
380 element
387 .append($('<div/>').text(msg).addClass('js-error'))
381 .append($('<div/>').text(msg).addClass('js-error'))
@@ -410,7 +404,7 b' define(['
410
404
411
405
412 OutputArea.prototype.append_execute_result = function (json) {
406 OutputArea.prototype.append_execute_result = function (json) {
413 var n = json.prompt_number || ' ';
407 var n = json.execution_count || ' ';
414 var toinsert = this.create_output_area();
408 var toinsert = this.create_output_area();
415 if (this.prompt_area) {
409 if (this.prompt_area) {
416 toinsert.find('div.prompt').addClass('output_prompt').text('Out[' + n + ']:');
410 toinsert.find('div.prompt').addClass('output_prompt').text('Out[' + n + ']:');
@@ -449,17 +443,12 b' define(['
449
443
450
444
451 OutputArea.prototype.append_stream = function (json) {
445 OutputArea.prototype.append_stream = function (json) {
452 // temporary fix: if stream undefined (json file written prior to this patch),
453 // default to most likely stdout:
454 if (json.stream === undefined){
455 json.stream = 'stdout';
456 }
457 var text = json.text;
446 var text = json.text;
458 var subclass = "output_"+json.stream;
447 var subclass = "output_"+json.name;
459 if (this.outputs.length > 0){
448 if (this.outputs.length > 0){
460 // have at least one output to consider
449 // have at least one output to consider
461 var last = this.outputs[this.outputs.length-1];
450 var last = this.outputs[this.outputs.length-1];
462 if (last.output_type == 'stream' && json.stream == last.stream){
451 if (last.output_type == 'stream' && json.name == last.name){
463 // latest output was in the same stream,
452 // latest output was in the same stream,
464 // so append directly into its pre tag
453 // so append directly into its pre tag
465 // escape ANSI & HTML specials:
454 // escape ANSI & HTML specials:
@@ -518,8 +507,8 b' define(['
518 for (var i=0; i < OutputArea.display_order.length; i++) {
507 for (var i=0; i < OutputArea.display_order.length; i++) {
519 var type = OutputArea.display_order[i];
508 var type = OutputArea.display_order[i];
520 var append = OutputArea.append_map[type];
509 var append = OutputArea.append_map[type];
521 if ((json[type] !== undefined) && append) {
510 if ((json.data[type] !== undefined) && append) {
522 var value = json[type];
511 var value = json.data[type];
523 if (!this.trusted && !OutputArea.safe_outputs[type]) {
512 if (!this.trusted && !OutputArea.safe_outputs[type]) {
524 // not trusted, sanitize HTML
513 // not trusted, sanitize HTML
525 if (type==='text/html' || type==='text/svg') {
514 if (type==='text/html' || type==='text/svg') {
@@ -722,11 +711,11 b' define(['
722 var toinsert = this.create_output_subarea(md, "output_pdf", type);
711 var toinsert = this.create_output_subarea(md, "output_pdf", type);
723 var a = $('<a/>').attr('href', 'data:application/pdf;base64,'+pdf);
712 var a = $('<a/>').attr('href', 'data:application/pdf;base64,'+pdf);
724 a.attr('target', '_blank');
713 a.attr('target', '_blank');
725 a.text('View PDF')
714 a.text('View PDF');
726 toinsert.append(a);
715 toinsert.append(a);
727 element.append(toinsert);
716 element.append(toinsert);
728 return toinsert;
717 return toinsert;
729 }
718 };
730
719
731 var append_latex = function (latex, md, element) {
720 var append_latex = function (latex, md, element) {
732 // This method cannot do the typesetting because the latex first has to
721 // This method cannot do the typesetting because the latex first has to
@@ -783,7 +772,7 b' define(['
783 // This seemed to be needed otherwise only the cell would be focused.
772 // This seemed to be needed otherwise only the cell would be focused.
784 // But with the modal UI, this seems to work fine with one call to focus().
773 // But with the modal UI, this seems to work fine with one call to focus().
785 raw_input.focus();
774 raw_input.focus();
786 }
775 };
787
776
788 OutputArea.prototype._submit_raw_input = function (evt) {
777 OutputArea.prototype._submit_raw_input = function (evt) {
789 var container = this.element.find("div.raw_input_container");
778 var container = this.element.find("div.raw_input_container");
@@ -799,13 +788,13 b' define(['
799 output_type : 'stream',
788 output_type : 'stream',
800 stream : 'stdout',
789 stream : 'stdout',
801 text : theprompt.text() + echo + '\n'
790 text : theprompt.text() + echo + '\n'
802 }
791 };
803 // remove form container
792 // remove form container
804 container.parent().remove();
793 container.parent().remove();
805 // replace with plaintext version in stdout
794 // replace with plaintext version in stdout
806 this.append_output(content, false);
795 this.append_output(content, false);
807 this.events.trigger('send_input_reply.Kernel', value);
796 this.events.trigger('send_input_reply.Kernel', value);
808 }
797 };
809
798
810
799
811 OutputArea.prototype.handle_clear_output = function (msg) {
800 OutputArea.prototype.handle_clear_output = function (msg) {
@@ -824,7 +813,7 b' define(['
824 // If a clear is queued, clear before adding another to the queue.
813 // If a clear is queued, clear before adding another to the queue.
825 if (this.clear_queued) {
814 if (this.clear_queued) {
826 this.clear_output(false);
815 this.clear_output(false);
827 };
816 }
828
817
829 this.clear_queued = true;
818 this.clear_queued = true;
830 } else {
819 } else {
@@ -846,76 +835,39 b' define(['
846 this.trusted = true;
835 this.trusted = true;
847 this.unscroll_area();
836 this.unscroll_area();
848 return;
837 return;
849 };
838 }
850 };
839 };
851
840
852
841
853 // JSON serialization
842 // JSON serialization
854
843
855 OutputArea.prototype.fromJSON = function (outputs) {
844 OutputArea.prototype.fromJSON = function (outputs, metadata) {
856 var len = outputs.length;
845 var len = outputs.length;
857 var data;
846 metadata = metadata || {};
858
847
859 for (var i=0; i<len; i++) {
848 for (var i=0; i<len; i++) {
860 data = outputs[i];
849 this.append_output(outputs[i]);
861 var msg_type = data.output_type;
850 }
862 if (msg_type == "pyout") {
851
863 // pyout message has been renamed to execute_result,
852 if (metadata.collapsed !== undefined) {
864 // but the nbformat has not been updated,
853 this.collapsed = metadata.collapsed;
865 // so transform back to pyout for json.
854 if (metadata.collapsed) {
866 msg_type = data.output_type = "execute_result";
855 this.collapse_output();
867 } else if (msg_type == "pyerr") {
868 // pyerr message has been renamed to error,
869 // but the nbformat has not been updated,
870 // so transform back to pyerr for json.
871 msg_type = data.output_type = "error";
872 }
856 }
873 if (msg_type === "display_data" || msg_type === "execute_result") {
857 }
874 // convert short keys to mime keys
858 if (metadata.autoscroll !== undefined) {
875 // TODO: remove mapping of short keys when we update to nbformat 4
859 this.collapsed = metadata.collapsed;
876 data = this.rename_keys(data, OutputArea.mime_map_r);
860 if (metadata.collapsed) {
877 data.metadata = this.rename_keys(data.metadata, OutputArea.mime_map_r);
861 this.collapse_output();
878 // msg spec JSON is an object, nbformat v3 JSON is a JSON string
862 } else {
879 if (data["application/json"] !== undefined && typeof data["application/json"] === 'string') {
863 this.expand_output();
880 data["application/json"] = JSON.parse(data["application/json"]);
881 }
882 }
864 }
883
884 this.append_output(data);
885 }
865 }
886 };
866 };
887
867
888
868
889 OutputArea.prototype.toJSON = function () {
869 OutputArea.prototype.toJSON = function () {
890 var outputs = [];
870 return this.outputs;
891 var len = this.outputs.length;
892 var data;
893 for (var i=0; i<len; i++) {
894 data = this.outputs[i];
895 var msg_type = data.output_type;
896 if (msg_type === "display_data" || msg_type === "execute_result") {
897 // convert mime keys to short keys
898 data = this.rename_keys(data, OutputArea.mime_map);
899 data.metadata = this.rename_keys(data.metadata, OutputArea.mime_map);
900 // msg spec JSON is an object, nbformat v3 JSON is a JSON string
901 if (data.json !== undefined && typeof data.json !== 'string') {
902 data.json = JSON.stringify(data.json);
903 }
904 }
905 if (msg_type == "execute_result") {
906 // pyout message has been renamed to execute_result,
907 // but the nbformat has not been updated,
908 // so transform back to pyout for json.
909 data.output_type = "pyout";
910 } else if (msg_type == "error") {
911 // pyerr message has been renamed to error,
912 // but the nbformat has not been updated,
913 // so transform back to pyerr for json.
914 data.output_type = "pyerr";
915 }
916 outputs[i] = data;
917 }
918 return outputs;
919 };
871 };
920
872
921 /**
873 /**
@@ -948,29 +900,6 b' define(['
948 OutputArea.minimum_scroll_threshold = 20;
900 OutputArea.minimum_scroll_threshold = 20;
949
901
950
902
951
952 OutputArea.mime_map = {
953 "text/plain" : "text",
954 "text/html" : "html",
955 "image/svg+xml" : "svg",
956 "image/png" : "png",
957 "image/jpeg" : "jpeg",
958 "text/latex" : "latex",
959 "application/json" : "json",
960 "application/javascript" : "javascript",
961 };
962
963 OutputArea.mime_map_r = {
964 "text" : "text/plain",
965 "html" : "text/html",
966 "svg" : "image/svg+xml",
967 "png" : "image/png",
968 "jpeg" : "image/jpeg",
969 "latex" : "text/latex",
970 "json" : "application/json",
971 "javascript" : "application/javascript",
972 };
973
974 OutputArea.display_order = [
903 OutputArea.display_order = [
975 'application/javascript',
904 'application/javascript',
976 'text/html',
905 'text/html',
@@ -222,6 +222,19 b' define(['
222
222
223 MarkdownCell.prototype = Object.create(TextCell.prototype);
223 MarkdownCell.prototype = Object.create(TextCell.prototype);
224
224
225 MarkdownCell.prototype.set_heading_level = function (level) {
226 // make a markdown cell a heading
227 level = level || 1;
228 var source = this.get_text();
229 source = source.replace(/^(#*)\s?/,
230 new Array(level + 1).join('#') + ' ');
231 this.set_text(source);
232 this.refresh();
233 if (this.rendered) {
234 this.render();
235 }
236 };
237
225 /**
238 /**
226 * @method render
239 * @method render
227 */
240 */
@@ -238,6 +251,19 b' define(['
238 html = mathjaxutils.replace_math(html, math);
251 html = mathjaxutils.replace_math(html, math);
239 html = security.sanitize_html(html);
252 html = security.sanitize_html(html);
240 html = $($.parseHTML(html));
253 html = $($.parseHTML(html));
254 // add anchors to headings
255 // console.log(html);
256 html.find(":header").addBack(":header").each(function (i, h) {
257 h = $(h);
258 var hash = h.text().replace(/ /g, '-');
259 h.attr('id', hash);
260 h.append(
261 $('<a/>')
262 .addClass('anchor-link')
263 .attr('href', '#' + hash)
264 .text('¶')
265 );
266 })
241 // links in markdown cells should open in new tabs
267 // links in markdown cells should open in new tabs
242 html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
268 html.find("a[href]").not('[href^="#"]').attr("target", "_blank");
243 this.set_rendered(html);
269 this.set_rendered(html);
@@ -305,121 +331,15 b' define(['
305 return cont;
331 return cont;
306 };
332 };
307
333
308
309 var HeadingCell = function (options) {
310 // Constructor
311 //
312 // Parameters:
313 // options: dictionary
314 // Dictionary of keyword arguments.
315 // events: $(Events) instance
316 // config: dictionary
317 // keyboard_manager: KeyboardManager instance
318 // notebook: Notebook instance
319 options = options || {};
320 var config = utils.mergeopt(HeadingCell, options.config);
321 TextCell.apply(this, [$.extend({}, options, {config: config})]);
322
323 this.level = 1;
324 this.cell_type = 'heading';
325 };
326
327 HeadingCell.options_default = {
328 cm_config: {
329 theme: 'heading-1'
330 },
331 placeholder: "Type Heading Here"
332 };
333
334 HeadingCell.prototype = Object.create(TextCell.prototype);
335
336 /** @method fromJSON */
337 HeadingCell.prototype.fromJSON = function (data) {
338 if (data.level !== undefined){
339 this.level = data.level;
340 }
341 TextCell.prototype.fromJSON.apply(this, arguments);
342 this.code_mirror.setOption("theme", "heading-"+this.level);
343 };
344
345
346 /** @method toJSON */
347 HeadingCell.prototype.toJSON = function () {
348 var data = TextCell.prototype.toJSON.apply(this);
349 data.level = this.get_level();
350 return data;
351 };
352
353 /**
354 * Change heading level of cell, and re-render
355 * @method set_level
356 */
357 HeadingCell.prototype.set_level = function (level) {
358 this.level = level;
359 this.code_mirror.setOption("theme", "heading-"+level);
360
361 if (this.rendered) {
362 this.rendered = false;
363 this.render();
364 }
365 };
366
367 /** The depth of header cell, based on html (h1 to h6)
368 * @method get_level
369 * @return {integer} level - for 1 to 6
370 */
371 HeadingCell.prototype.get_level = function () {
372 return this.level;
373 };
374
375
376 HeadingCell.prototype.get_rendered = function () {
377 var r = this.element.find("div.text_cell_render");
378 return r.children().first().html();
379 };
380
381 HeadingCell.prototype.render = function () {
382 var cont = TextCell.prototype.render.apply(this);
383 if (cont) {
384 var text = this.get_text();
385 var math = null;
386 // Markdown headings must be a single line
387 text = text.replace(/\n/g, ' ');
388 if (text === "") { text = this.placeholder; }
389 text = new Array(this.level + 1).join("#") + " " + text;
390 var text_and_math = mathjaxutils.remove_math(text);
391 text = text_and_math[0];
392 math = text_and_math[1];
393 var html = marked.parser(marked.lexer(text));
394 html = mathjaxutils.replace_math(html, math);
395 html = security.sanitize_html(html);
396 var h = $($.parseHTML(html));
397 // add id and linkback anchor
398 var hash = h.text().trim().replace(/ /g, '-');
399 h.attr('id', hash);
400 h.append(
401 $('<a/>')
402 .addClass('anchor-link')
403 .attr('href', '#' + hash)
404 .text('¶')
405 );
406 this.set_rendered(h);
407 this.typeset();
408 }
409 return cont;
410 };
411
412 // Backwards compatability.
334 // Backwards compatability.
413 IPython.TextCell = TextCell;
335 IPython.TextCell = TextCell;
414 IPython.MarkdownCell = MarkdownCell;
336 IPython.MarkdownCell = MarkdownCell;
415 IPython.RawCell = RawCell;
337 IPython.RawCell = RawCell;
416 IPython.HeadingCell = HeadingCell;
417
338
418 var textcell = {
339 var textcell = {
419 'TextCell': TextCell,
340 TextCell: TextCell,
420 'MarkdownCell': MarkdownCell,
341 MarkdownCell: MarkdownCell,
421 'RawCell': RawCell,
342 RawCell: RawCell,
422 'HeadingCell': HeadingCell,
423 };
343 };
424 return textcell;
344 return textcell;
425 });
345 });
@@ -36,7 +36,6 b' div.cell.text_cell.rendered {'
36 padding: 0px;
36 padding: 0px;
37 }
37 }
38
38
39
40 .text_cell.rendered .input_area {
39 .text_cell.rendered .input_area {
41 display: none;
40 display: none;
42 }
41 }
@@ -45,25 +44,25 b' div.cell.text_cell.rendered {'
45 display:none;
44 display:none;
46 }
45 }
47
46
48 .cm-s-heading-1,
47 .cm-header-1,
49 .cm-s-heading-2,
48 .cm-header-2,
50 .cm-s-heading-3,
49 .cm-header-3,
51 .cm-s-heading-4,
50 .cm-header-4,
52 .cm-s-heading-5,
51 .cm-header-5,
53 .cm-s-heading-6 {
52 .cm-header-6 {
54 font-weight: bold;
53 font-weight: bold;
55 font-family: @font-family-sans-serif;
54 font-family: @font-family-sans-serif;
56 }
55 }
57
56
58 .cm-s-heading-1 { font-size:150%; }
57 .cm-header-1 { font-size: 185.7%; }
59 .cm-s-heading-2 { font-size: 130%; }
58 .cm-header-2 { font-size: 157.1%; }
60 .cm-s-heading-3 { font-size: 120%; }
59 .cm-header-3 { font-size: 128.6%; }
61 .cm-s-heading-4 { font-size: 110%; }
60 .cm-header-4 { font-size: 110%; }
62 .cm-s-heading-5 {
61 .cm-header-5 {
63 font-size: 100%;
62 font-size: 100%;
64 font-style: italic;
63 font-style: italic;
65 }
64 }
66 .cm-s-heading-6 {
65 .cm-header-6 {
67 font-size: 90%;
66 font-size: 100%;
68 font-style: italic;
67 font-style: italic;
69 }
68 }
@@ -1116,33 +1116,33 b' div.cell.text_cell.rendered {'
1116 .text_cell.unrendered .text_cell_render {
1116 .text_cell.unrendered .text_cell_render {
1117 display: none;
1117 display: none;
1118 }
1118 }
1119 .cm-s-heading-1,
1119 .cm-header-1,
1120 .cm-s-heading-2,
1120 .cm-header-2,
1121 .cm-s-heading-3,
1121 .cm-header-3,
1122 .cm-s-heading-4,
1122 .cm-header-4,
1123 .cm-s-heading-5,
1123 .cm-header-5,
1124 .cm-s-heading-6 {
1124 .cm-header-6 {
1125 font-weight: bold;
1125 font-weight: bold;
1126 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1126 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
1127 }
1127 }
1128 .cm-s-heading-1 {
1128 .cm-header-1 {
1129 font-size: 150%;
1129 font-size: 185.7%;
1130 }
1130 }
1131 .cm-s-heading-2 {
1131 .cm-header-2 {
1132 font-size: 130%;
1132 font-size: 157.1%;
1133 }
1133 }
1134 .cm-s-heading-3 {
1134 .cm-header-3 {
1135 font-size: 120%;
1135 font-size: 128.6%;
1136 }
1136 }
1137 .cm-s-heading-4 {
1137 .cm-header-4 {
1138 font-size: 110%;
1138 font-size: 110%;
1139 }
1139 }
1140 .cm-s-heading-5 {
1140 .cm-header-5 {
1141 font-size: 100%;
1141 font-size: 100%;
1142 font-style: italic;
1142 font-style: italic;
1143 }
1143 }
1144 .cm-s-heading-6 {
1144 .cm-header-6 {
1145 font-size: 90%;
1145 font-size: 100%;
1146 font-style: italic;
1146 font-style: italic;
1147 }
1147 }
1148 .widget-area {
1148 .widget-area {
@@ -8985,33 +8985,33 b' div.cell.text_cell.rendered {'
8985 .text_cell.unrendered .text_cell_render {
8985 .text_cell.unrendered .text_cell_render {
8986 display: none;
8986 display: none;
8987 }
8987 }
8988 .cm-s-heading-1,
8988 .cm-header-1,
8989 .cm-s-heading-2,
8989 .cm-header-2,
8990 .cm-s-heading-3,
8990 .cm-header-3,
8991 .cm-s-heading-4,
8991 .cm-header-4,
8992 .cm-s-heading-5,
8992 .cm-header-5,
8993 .cm-s-heading-6 {
8993 .cm-header-6 {
8994 font-weight: bold;
8994 font-weight: bold;
8995 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
8995 font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
8996 }
8996 }
8997 .cm-s-heading-1 {
8997 .cm-header-1 {
8998 font-size: 150%;
8998 font-size: 185.7%;
8999 }
8999 }
9000 .cm-s-heading-2 {
9000 .cm-header-2 {
9001 font-size: 130%;
9001 font-size: 157.1%;
9002 }
9002 }
9003 .cm-s-heading-3 {
9003 .cm-header-3 {
9004 font-size: 120%;
9004 font-size: 128.6%;
9005 }
9005 }
9006 .cm-s-heading-4 {
9006 .cm-header-4 {
9007 font-size: 110%;
9007 font-size: 110%;
9008 }
9008 }
9009 .cm-s-heading-5 {
9009 .cm-header-5 {
9010 font-size: 100%;
9010 font-size: 100%;
9011 font-style: italic;
9011 font-style: italic;
9012 }
9012 }
9013 .cm-s-heading-6 {
9013 .cm-header-6 {
9014 font-size: 90%;
9014 font-size: 100%;
9015 font-style: italic;
9015 font-style: italic;
9016 }
9016 }
9017 .widget-area {
9017 .widget-area {
@@ -189,12 +189,6 b' class="notebook_app"'
189 <li id="to_raw"
189 <li id="to_raw"
190 title="Contents will pass through nbconvert unmodified">
190 title="Contents will pass through nbconvert unmodified">
191 <a href="#">Raw NBConvert</a></li>
191 <a href="#">Raw NBConvert</a></li>
192 <li id="to_heading1"><a href="#">Heading 1</a></li>
193 <li id="to_heading2"><a href="#">Heading 2</a></li>
194 <li id="to_heading3"><a href="#">Heading 3</a></li>
195 <li id="to_heading4"><a href="#">Heading 4</a></li>
196 <li id="to_heading5"><a href="#">Heading 5</a></li>
197 <li id="to_heading6"><a href="#">Heading 6</a></li>
198 </ul>
192 </ul>
199 </li>
193 </li>
200 <li class="divider"></li>
194 <li class="divider"></li>
@@ -52,12 +52,12 b' casper.notebook_test(function () {'
52
52
53 this.then(function () {
53 this.then(function () {
54 this.select_cell(2);
54 this.select_cell(2);
55 this.trigger_keydown('1'); // switch it to heading for the next test
55 this.trigger_keydown('y'); // switch it to code for the next test
56 this.test.assertEquals(this.get_cell(2).cell_type, 'heading', 'test cell is heading');
56 this.test.assertEquals(this.get_cell(2).cell_type, 'code', 'test cell is code');
57 this.trigger_keydown('b'); // new cell below
57 this.trigger_keydown('b'); // new cell below
58 this.test.assertEquals(this.get_cell(3).cell_type, 'heading', 'b; inserts a heading cell below heading cell');
58 this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'b; inserts a code cell below code cell');
59 this.trigger_keydown('a'); // new cell above
59 this.trigger_keydown('a'); // new cell above
60 this.test.assertEquals(this.get_cell(3).cell_type, 'heading', 'a; inserts a heading cell below heading cell');
60 this.test.assertEquals(this.get_cell(3).cell_type, 'code', 'a; inserts a code cell above code cell');
61 });
61 });
62
62
63 this.thenEvaluate(function() {
63 this.thenEvaluate(function() {
@@ -72,6 +72,6 b' casper.notebook_test(function () {'
72 this.test.assertEquals(this.get_cell(2).cell_type, 'raw', 'a; inserts a raw cell above raw cell');
72 this.test.assertEquals(this.get_cell(2).cell_type, 'raw', 'a; inserts a raw cell above raw cell');
73 this.trigger_keydown('y'); // switch it to code for the next test
73 this.trigger_keydown('y'); // switch it to code for the next test
74 this.trigger_keydown('b'); // new cell below
74 this.trigger_keydown('b'); // new cell below
75 this.test.assertEquals(this.get_cell(3).cell_type, 'raw', 'b; inserts a raw cell above raw cell');
75 this.test.assertEquals(this.get_cell(3).cell_type, 'raw', 'b; inserts a raw cell below raw cell');
76 });
76 });
77 });
77 });
@@ -4,25 +4,38 b''
4 casper.notebook_test(function () {
4 casper.notebook_test(function () {
5 this.then(function () {
5 this.then(function () {
6 // Cell mode change
6 // Cell mode change
7 this.select_cell(0);
7 var index = 0;
8 this.select_cell(index);
9 var a = 'hello\nmulti\nline';
10 this.set_cell_text(index, a);
8 this.trigger_keydown('esc','r');
11 this.trigger_keydown('esc','r');
9 this.test.assertEquals(this.get_cell(0).cell_type, 'raw', 'r; cell is raw');
12 this.test.assertEquals(this.get_cell(index).cell_type, 'raw', 'r; cell is raw');
10 this.trigger_keydown('1');
13 this.trigger_keydown('1');
11 this.test.assertEquals(this.get_cell(0).cell_type, 'heading', '1; cell is heading');
14 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '1; cell is markdown');
12 this.test.assertEquals(this.get_cell(0).level, 1, '1; cell is level 1 heading');
15 this.test.assertEquals(this.get_cell_text(index), '# ' + a, '1; markdown heading');
13 this.trigger_keydown('2');
16 this.trigger_keydown('2');
14 this.test.assertEquals(this.get_cell(0).level, 2, '2; cell is level 2 heading');
17 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '2; cell is markdown');
18 this.test.assertEquals(this.get_cell_text(index), '## ' + a, '2; markdown heading');
15 this.trigger_keydown('3');
19 this.trigger_keydown('3');
16 this.test.assertEquals(this.get_cell(0).level, 3, '3; cell is level 3 heading');
20 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '3; cell is markdown');
21 this.test.assertEquals(this.get_cell_text(index), '### ' + a, '3; markdown heading');
17 this.trigger_keydown('4');
22 this.trigger_keydown('4');
18 this.test.assertEquals(this.get_cell(0).level, 4, '4; cell is level 4 heading');
23 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '4; cell is markdown');
24 this.test.assertEquals(this.get_cell_text(index), '#### ' + a, '4; markdown heading');
19 this.trigger_keydown('5');
25 this.trigger_keydown('5');
20 this.test.assertEquals(this.get_cell(0).level, 5, '5; cell is level 5 heading');
26 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '5; cell is markdown');
27 this.test.assertEquals(this.get_cell_text(index), '##### ' + a, '5; markdown heading');
21 this.trigger_keydown('6');
28 this.trigger_keydown('6');
22 this.test.assertEquals(this.get_cell(0).level, 6, '6; cell is level 6 heading');
29 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '6; cell is markdown');
30 this.test.assertEquals(this.get_cell_text(index), '###### ' + a, '6; markdown heading');
23 this.trigger_keydown('m');
31 this.trigger_keydown('m');
24 this.test.assertEquals(this.get_cell(0).cell_type, 'markdown', 'm; cell is markdown');
32 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', 'm; cell is markdown');
33 this.test.assertEquals(this.get_cell_text(index), '###### ' + a, 'm; still markdown heading');
25 this.trigger_keydown('y');
34 this.trigger_keydown('y');
26 this.test.assertEquals(this.get_cell(0).cell_type, 'code', 'y; cell is code');
35 this.test.assertEquals(this.get_cell(index).cell_type, 'code', 'y; cell is code');
36 this.test.assertEquals(this.get_cell_text(index), '###### ' + a, 'y; still has hashes');
37 this.trigger_keydown('1');
38 this.test.assertEquals(this.get_cell(index).cell_type, 'markdown', '1; cell is markdown');
39 this.test.assertEquals(this.get_cell_text(index), '# ' + a, '1; markdown heading');
27 });
40 });
28 }); No newline at end of file
41 });
@@ -13,7 +13,7 b' casper.notebook_test(function () {'
13 this.evaluate(function () {
13 this.evaluate(function () {
14 var cell = IPython.notebook.get_cell(0);
14 var cell = IPython.notebook.get_cell(0);
15 var json = cell.toJSON();
15 var json = cell.toJSON();
16 json.prompt_number = "<script> alert('hello from input prompts !')</script>";
16 json.execution_count = "<script> alert('hello from input prompts !')</script>";
17 cell.fromJSON(json);
17 cell.fromJSON(json);
18 });
18 });
19
19
@@ -10,38 +10,53 b' casper.notebook_test(function () {'
10 cell.render();
10 cell.render();
11 return cell.get_rendered();
11 return cell.get_rendered();
12 });
12 });
13 this.test.assertEquals(output.trim(), '<h1 id=\"foo\">Foo</h1>', 'Markdown JS API works.');
13 this.test.assertEquals(output.trim(), '<h1 id=\"Foo\">Foo<a class=\"anchor-link\" href=\"#Foo\">¶</a></h1>', 'Markdown JS API works.');
14
14
15 // Test menubar entries.
15 // Test menubar entries.
16 output = this.evaluate(function () {
16 output = this.evaluate(function () {
17 $('#to_code').mouseenter().click();
17 $('#to_code').mouseenter().click();
18 $('#to_markdown').mouseenter().click();
18 $('#to_markdown').mouseenter().click();
19 var cell = IPython.notebook.get_selected_cell();
19 var cell = IPython.notebook.get_selected_cell();
20 cell.set_text('# Bar');
20 cell.set_text('**Bar**');
21 $('#run_cell').mouseenter().click();
21 $('#run_cell').mouseenter().click();
22 return cell.get_rendered();
22 return cell.get_rendered();
23 });
23 });
24 this.test.assertEquals(output.trim(), '<h1 id=\"bar\">Bar</h1>', 'Markdown menubar items work.');
24 this.test.assertEquals(output.trim(), '<p><strong>Bar</strong></p>', 'Markdown menubar items work.');
25
25
26 // Test toolbar buttons.
26 // Test toolbar buttons.
27 output = this.evaluate(function () {
27 output = this.evaluate(function () {
28 $('#cell_type').val('code').change();
28 $('#cell_type').val('code').change();
29 $('#cell_type').val('markdown').change();
29 $('#cell_type').val('markdown').change();
30 var cell = IPython.notebook.get_selected_cell();
30 var cell = IPython.notebook.get_selected_cell();
31 cell.set_text('# Baz');
31 cell.set_text('*Baz*');
32 $('#run_b').click();
32 $('#run_b').click();
33 return cell.get_rendered();
33 return cell.get_rendered();
34 });
34 });
35 this.test.assertEquals(output.trim(), '<h1 id=\"baz\">Baz</h1>', 'Markdown toolbar items work.');
35 this.test.assertEquals(output.trim(), '<p><em>Baz</em></p>', 'Markdown toolbar items work.');
36
36
37 // Test JavaScript models.
37 // Test markdown headings
38 var output = this.evaluate(function () {
39
38
39 var text = 'multi\nline';
40
41 this.evaluate(function (text) {
40 var cell = IPython.notebook.insert_cell_at_index('markdown', 0);
42 var cell = IPython.notebook.insert_cell_at_index('markdown', 0);
41 cell.set_text('# Qux');
43 cell.set_text(text);
42 cell.render();
44 }, {text: text});
43 return cell.get_rendered();
45
44 });
46 var set_level = function (level) {
45 this.test.assertEquals(output.trim(), '<h1 id=\"qux\">Qux</h1>', 'Markdown JS API works.');
47 return casper.evaluate(function (level) {
48 var cell = IPython.notebook.get_cell(0);
49 cell.set_heading_level(level);
50 return cell.get_text();
51 }, {level: level});
52 };
46
53
54 var level_text;
55 var levels = [ 1, 2, 3, 4, 5, 6, 2, 1 ];
56 for (var idx=0; idx < levels.length; idx++) {
57 var level = levels[idx];
58 level_text = set_level(level);
59 hashes = new Array(level + 1).join('#');
60 this.test.assertEquals(level_text, hashes + ' ' + text, 'markdown set_heading_level ' + level);
61 }
47 });
62 });
@@ -29,7 +29,7 b' casper.notebook_test(function () {'
29 var ex = expected[i];
29 var ex = expected[i];
30 this.test.assertEquals(r.output_type, ex.output_type, "output " + i);
30 this.test.assertEquals(r.output_type, ex.output_type, "output " + i);
31 if (r.output_type === 'stream') {
31 if (r.output_type === 'stream') {
32 this.test.assertEquals(r.stream, ex.stream, "stream " + i);
32 this.test.assertEquals(r.name, ex.name, "stream " + i);
33 this.test.assertEquals(r.text, ex.text, "content " + i);
33 this.test.assertEquals(r.text, ex.text, "content " + i);
34 }
34 }
35 }
35 }
@@ -57,7 +57,7 b' casper.notebook_test(function () {'
57 "print(3)"
57 "print(3)"
58 ].join("\n"), [{
58 ].join("\n"), [{
59 output_type: "stream",
59 output_type: "stream",
60 stream: "stdout",
60 name: "stdout",
61 text: "1\n2\n3\n"
61 text: "1\n2\n3\n"
62 }]
62 }]
63 );
63 );
@@ -69,11 +69,11 b' casper.notebook_test(function () {'
69 "print(3, file=sys.stderr)"
69 "print(3, file=sys.stderr)"
70 ].join("\n"), [{
70 ].join("\n"), [{
71 output_type: "stream",
71 output_type: "stream",
72 stream: "stdout",
72 name: "stdout",
73 text: "1\n2\n"
73 text: "1\n2\n"
74 },{
74 },{
75 output_type: "stream",
75 output_type: "stream",
76 stream: "stderr",
76 name: "stderr",
77 text: "3\n"
77 text: "3\n"
78 }]
78 }]
79 );
79 );
@@ -85,13 +85,13 b' casper.notebook_test(function () {'
85 "print(3)"
85 "print(3)"
86 ].join("\n"), [{
86 ].join("\n"), [{
87 output_type: "stream",
87 output_type: "stream",
88 stream: "stdout",
88 name: "stdout",
89 text: "1\n"
89 text: "1\n"
90 },{
90 },{
91 output_type: "display_data",
91 output_type: "display_data",
92 },{
92 },{
93 output_type: "stream",
93 output_type: "stream",
94 stream: "stdout",
94 name: "stdout",
95 text: "3\n"
95 text: "3\n"
96 }]
96 }]
97 );
97 );
@@ -14,7 +14,7 b' mime = {'
14 "json" : "application/json",
14 "json" : "application/json",
15 "javascript" : "application/javascript",
15 "javascript" : "application/javascript",
16 };
16 };
17
17
18 var black_dot_jpeg="u\"\"\"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDACodICUgGiolIiUvLSoyP2lEPzo6P4FcYUxpmYagnpaG\nk5GovfLNqLPltZGT0v/V5fr/////o8v///////L/////2wBDAS0vLz83P3xERHz/rpOu////////\n////////////////////////////////////////////////////////////wgARCAABAAEDAREA\nAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAABP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEA\nAhADEAAAARn/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAEFAn//xAAUEQEAAAAAAAAAAAAA\nAAAAAAAA/9oACAEDAQE/AX//xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oACAECAQE/AX//xAAUEAEA\nAAAAAAAAAAAAAAAAAAAA/9oACAEBAAY/An//xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAE/\nIX//2gAMAwEAAgADAAAAEB//xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oACAEDAQE/EH//xAAUEQEA\nAAAAAAAAAAAAAAAAAAAA/9oACAECAQE/EH//xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAE/\nEH//2Q==\"\"\"";
18 var black_dot_jpeg="u\"\"\"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDACodICUgGiolIiUvLSoyP2lEPzo6P4FcYUxpmYagnpaG\nk5GovfLNqLPltZGT0v/V5fr/////o8v///////L/////2wBDAS0vLz83P3xERHz/rpOu////////\n////////////////////////////////////////////////////////////wgARCAABAAEDAREA\nAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAABP/EABQBAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEA\nAhADEAAAARn/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAEFAn//xAAUEQEAAAAAAAAAAAAA\nAAAAAAAA/9oACAEDAQE/AX//xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oACAECAQE/AX//xAAUEAEA\nAAAAAAAAAAAAAAAAAAAA/9oACAEBAAY/An//xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAE/\nIX//2gAMAwEAAgADAAAAEB//xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oACAEDAQE/EH//xAAUEQEA\nAAAAAAAAAAAAAAAAAAAA/9oACAECAQE/EH//xAAUEAEAAAAAAAAAAAAAAAAAAAAA/9oACAEBAAE/\nEH//2Q==\"\"\"";
19 var black_dot_png = 'u\"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QA\\niAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AA\\nAAACAAHiIbwzAAAAAElFTkSuQmCC\"';
19 var black_dot_png = 'u\"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAWJLR0QA\\niAUdSAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB94BCRQnOqNu0b4AAAAKSURBVAjXY2AA\\nAAACAAHiIbwzAAAAAElFTkSuQmCC\"';
20 var svg = "\"<svg width='1cm' height='1cm' viewBox='0 0 1000 500'><defs><style>rect {fill:red;}; </style></defs><rect id='r1' x='200' y='100' width='600' height='300' /></svg>\"";
20 var svg = "\"<svg width='1cm' height='1cm' viewBox='0 0 1000 500'><defs><style>rect {fill:red;}; </style></defs><rect id='r1' x='200' y='100' width='600' height='300' /></svg>\"";
@@ -24,18 +24,20 b' var svg = "\\"<svg width=\'1cm\' height=\'1cm\' viewBox=\'0 0 1000 500\'><defs><style>r'
24 // name, and that fromJSON also gets its long mimetype name
24 // name, and that fromJSON also gets its long mimetype name
25 function assert_has(short_name, json, result, result2) {
25 function assert_has(short_name, json, result, result2) {
26 long_name = mime[short_name];
26 long_name = mime[short_name];
27 this.test.assertTrue(json[0].hasOwnProperty(short_name),
27 this.test.assertFalse(json[0].data.hasOwnProperty(short_name),
28 'toJSON() representation uses ' + short_name);
28 "toJSON() representation doesn't use " + short_name);
29 this.test.assertTrue(result.hasOwnProperty(long_name),
29 this.test.assertTrue(json[0].data.hasOwnProperty(long_name),
30 'toJSON() representation uses ' + long_name);
31 this.test.assertTrue(result.data.hasOwnProperty(long_name),
30 'toJSON() original embedded JSON keeps ' + long_name);
32 'toJSON() original embedded JSON keeps ' + long_name);
31 this.test.assertTrue(result2.hasOwnProperty(long_name),
33 this.test.assertTrue(result2.data.hasOwnProperty(long_name),
32 'fromJSON() embedded ' + short_name + ' gets mime key ' + long_name);
34 'fromJSON() embedded ' + short_name + ' gets mime key ' + long_name);
33 }
35 }
34
36
35 // helper function for checkout that the first two cells have a particular
37 // helper function for checkout that the first two cells have a particular
36 // output_type (either 'execute_result' or 'display_data'), and checks the to/fromJSON
38 // output_type (either 'execute_result' or 'display_data'), and checks the to/fromJSON
37 // for a set of mimetype keys, using their short names ('javascript', 'text',
39 // for a set of mimetype keys, ensuring the old short names ('javascript', 'text',
38 // 'png', etc).
40 // 'png', etc) are not used.
39 function check_output_area(output_type, keys) {
41 function check_output_area(output_type, keys) {
40 this.wait_for_output(0);
42 this.wait_for_output(0);
41 json = this.evaluate(function() {
43 json = this.evaluate(function() {
@@ -69,7 +71,7 b' function clear_and_execute(that, code) {'
69 that.execute_cell(0);
71 that.execute_cell(0);
70 that.wait_for_idle();
72 that.wait_for_idle();
71 });
73 });
72 };
74 }
73
75
74 casper.notebook_test(function () {
76 casper.notebook_test(function () {
75 this.evaluate(function () {
77 this.evaluate(function () {
@@ -86,7 +88,7 b' casper.notebook_test(function () {'
86 var result = this.get_output_cell(0);
88 var result = this.get_output_cell(0);
87 var num_cells = this.get_cells_length();
89 var num_cells = this.get_cells_length();
88 this.test.assertEquals(num_cells, 2, '%%javascript magic works');
90 this.test.assertEquals(num_cells, 2, '%%javascript magic works');
89 this.test.assertTrue(result.hasOwnProperty('application/javascript'),
91 this.test.assertTrue(result.data.hasOwnProperty('application/javascript'),
90 'testing JS embedded with mime key');
92 'testing JS embedded with mime key');
91 });
93 });
92
94
@@ -234,10 +236,10 b' casper.notebook_test(function () {'
234 this.then(function () {
236 this.then(function () {
235 var long_name = 'text/superfancymimetype';
237 var long_name = 'text/superfancymimetype';
236 var result = this.get_output_cell(0);
238 var result = this.get_output_cell(0);
237 this.test.assertTrue(result.hasOwnProperty(long_name),
239 this.test.assertTrue(result.data.hasOwnProperty(long_name),
238 'display_data custom mimetype ' + long_name);
240 'display_data custom mimetype ' + long_name);
239 var result = this.get_output_cell(0, 1);
241 result = this.get_output_cell(0, 1);
240 this.test.assertTrue(result.hasOwnProperty(long_name),
242 this.test.assertTrue(result.data.hasOwnProperty(long_name),
241 'execute_result custom mimetype ' + long_name);
243 'execute_result custom mimetype ' + long_name);
242
244
243 });
245 });
@@ -26,7 +26,7 b' casper.notebook_test(function () {'
26 var output = this.get_output_cell(0);
26 var output = this.get_output_cell(0);
27 this.test.assert(messages.length > 0, "Captured log message");
27 this.test.assert(messages.length > 0, "Captured log message");
28 this.test.assertEquals(messages[messages.length-1].substr(0,26), "Invalid type for image/png", "Logged Invalid type message");
28 this.test.assertEquals(messages[messages.length-1].substr(0,26), "Invalid type for image/png", "Logged Invalid type message");
29 this.test.assertEquals(output['image/png'], undefined, "Non-string png data was stripped");
29 this.test.assertEquals(output.data['image/png'], undefined, "Non-string png data was stripped");
30 this.test.assertEquals(output['text/plain'], '5', "text data is fine");
30 this.test.assertEquals(output.data['text/plain'], '5', "text data is fine");
31 });
31 });
32 });
32 });
@@ -10,8 +10,9 b' pjoin = os.path.join'
10 import requests
10 import requests
11 import json
11 import json
12
12
13 from IPython.nbformat.current import (new_notebook, write, new_worksheet,
13 from IPython.nbformat import write
14 new_heading_cell, new_code_cell,
14 from IPython.nbformat.v4 import (new_notebook,
15 new_markdown_cell, new_code_cell,
15 new_output)
16 new_output)
16
17
17 from IPython.html.utils import url_path_join
18 from IPython.html.utils import url_path_join
@@ -62,18 +63,18 b' class FilesTest(NotebookTestBase):'
62 nbdir = self.notebook_dir.name
63 nbdir = self.notebook_dir.name
63 base = self.base_url()
64 base = self.base_url()
64
65
65 nb = new_notebook(name='testnb')
66 nb = new_notebook(
66
67 cells=[
67 ws = new_worksheet()
68 new_markdown_cell(u'Created by test ³'),
68 nb.worksheets = [ws]
69 new_code_cell("print(2*6)", outputs=[
69 ws.cells.append(new_heading_cell(u'Created by test ³'))
70 new_output("stream", text="12"),
70 cc1 = new_code_cell(input=u'print(2*6)')
71 ])
71 cc1.outputs.append(new_output(output_text=u'12', output_type='stream'))
72 ]
72 ws.cells.append(cc1)
73 )
73
74
74 with io.open(pjoin(nbdir, 'testnb.ipynb'), 'w',
75 with io.open(pjoin(nbdir, 'testnb.ipynb'), 'w',
75 encoding='utf-8') as f:
76 encoding='utf-8') as f:
76 write(nb, f, format='ipynb')
77 write(nb, f, version=4)
77
78
78 with io.open(pjoin(nbdir, 'test.bin'), 'wb') as f:
79 with io.open(pjoin(nbdir, 'test.bin'), 'wb') as f:
79 f.write(b'\xff' + os.urandom(5))
80 f.write(b'\xff' + os.urandom(5))
@@ -170,7 +170,7 b' casper.notebook_test(function () {'
170 this.test.assert(outputs.length <= 5, 'Messages throttled.');
170 this.test.assert(outputs.length <= 5, 'Messages throttled.');
171
171
172 // We also need to verify that the last state sent was correct.
172 // We also need to verify that the last state sent was correct.
173 var last_state = outputs[outputs.length-1]['text/plain'];
173 var last_state = outputs[outputs.length-1].data['text/plain'];
174 this.test.assertEquals(last_state, "20", "Last state sent when throttling.");
174 this.test.assertEquals(last_state, "20", "Last state sent when throttling.");
175 });
175 });
176 });
176 });
@@ -37,7 +37,7 b' casper.notebook_test(function () {'
37 this.wait_for_output(button_index, 1);
37 this.wait_for_output(button_index, 1);
38
38
39 this.then(function () {
39 this.then(function () {
40 this.test.assertEquals(this.get_output_cell(button_index, 1)['text/plain'], "'Clicked'",
40 this.test.assertEquals(this.get_output_cell(button_index, 1).data['text/plain'], "'Clicked'",
41 'Button click event fires.');
41 'Button click event fires.');
42 });
42 });
43 }); No newline at end of file
43 });
@@ -5,7 +5,7 b''
5
5
6 from functools import wraps
6 from functools import wraps
7
7
8 from IPython.nbformat.v3.nbbase import NotebookNode
8 from IPython.nbformat import NotebookNode
9 from IPython.utils.decorators import undoc
9 from IPython.utils.decorators import undoc
10 from IPython.utils.py3compat import string_types
10 from IPython.utils.py3compat import string_types
11
11
@@ -29,7 +29,7 b' def DocDecorator(f):'
29
29
30 #Set docstring of function
30 #Set docstring of function
31 f.__doc__ = f.__doc__ + """
31 f.__doc__ = f.__doc__ + """
32 nb : :class:`~{nbnode_mod}.NotebookNode`
32 nb : :class:`~IPython.nbformat.NotebookNode`
33 The notebook to export.
33 The notebook to export.
34 config : config (optional, keyword arg)
34 config : config (optional, keyword arg)
35 User configuration instance.
35 User configuration instance.
@@ -52,7 +52,7 b' def DocDecorator(f):'
52 Notes
52 Notes
53 -----
53 -----
54 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
54 WARNING: API WILL CHANGE IN FUTURE RELEASES OF NBCONVERT
55 """.format(nbnode_mod=NotebookNode.__module__)
55 """
56
56
57 @wraps(f)
57 @wraps(f)
58 def decorator(*args, **kwargs):
58 def decorator(*args, **kwargs):
@@ -2,39 +2,22 b''
2 see templateexporter.py.
2 see templateexporter.py.
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
5
17 from __future__ import print_function, absolute_import
6 from __future__ import print_function, absolute_import
18
7
19 # Stdlib imports
20 import io
8 import io
21 import os
9 import os
22 import copy
10 import copy
23 import collections
11 import collections
24 import datetime
12 import datetime
25
13
26
27 # IPython imports
28 from IPython.config.configurable import LoggingConfigurable
14 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config import Config
15 from IPython.config import Config
30 from IPython.nbformat import current as nbformat
16 from IPython import nbformat
31 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
17 from IPython.utils.traitlets import MetaHasTraits, Unicode, List
32 from IPython.utils.importstring import import_item
18 from IPython.utils.importstring import import_item
33 from IPython.utils import text, py3compat
19 from IPython.utils import text, py3compat
34
20
35 #-----------------------------------------------------------------------------
36 # Class
37 #-----------------------------------------------------------------------------
38
21
39 class ResourcesDict(collections.defaultdict):
22 class ResourcesDict(collections.defaultdict):
40 def __missing__(self, key):
23 def __missing__(self, key):
@@ -106,8 +89,8 b' class Exporter(LoggingConfigurable):'
106
89
107 Parameters
90 Parameters
108 ----------
91 ----------
109 nb : :class:`~IPython.nbformat.current.NotebookNode`
92 nb : :class:`~IPython.nbformat.NotebookNode`
110 Notebook node
93 Notebook node (dict-like with attr-access)
111 resources : dict
94 resources : dict
112 Additional resources that can be accessed read/write by
95 Additional resources that can be accessed read/write by
113 preprocessors and filters.
96 preprocessors and filters.
@@ -149,7 +132,7 b' class Exporter(LoggingConfigurable):'
149 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
132 resources['metadata']['modified_date'] = modified_date.strftime(text.date_format)
150
133
151 with io.open(filename, encoding='utf-8') as f:
134 with io.open(filename, encoding='utf-8') as f:
152 return self.from_notebook_node(nbformat.read(f, 'json'), resources=resources, **kw)
135 return self.from_notebook_node(nbformat.read(f, as_version=4), resources=resources, **kw)
153
136
154
137
155 def from_file(self, file_stream, resources=None, **kw):
138 def from_file(self, file_stream, resources=None, **kw):
@@ -161,7 +144,7 b' class Exporter(LoggingConfigurable):'
161 file_stream : file-like object
144 file_stream : file-like object
162 Notebook file-like object to convert.
145 Notebook file-like object to convert.
163 """
146 """
164 return self.from_notebook_node(nbformat.read(file_stream, 'json'), resources=resources, **kw)
147 return self.from_notebook_node(nbformat.read(file_stream, as_version=4), resources=resources, **kw)
165
148
166
149
167 def register_preprocessor(self, preprocessor, enabled=False):
150 def register_preprocessor(self, preprocessor, enabled=False):
@@ -46,7 +46,7 b' class HTMLExporter(TemplateExporter):'
46 def default_config(self):
46 def default_config(self):
47 c = Config({
47 c = Config({
48 'NbConvertBase': {
48 'NbConvertBase': {
49 'display_data_priority' : ['javascript', 'html', 'application/pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text']
49 'display_data_priority' : ['text/javascript', 'text/html', 'application/pdf', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain']
50 },
50 },
51 'CSSHTMLHeaderPreprocessor':{
51 'CSSHTMLHeaderPreprocessor':{
52 'enabled':True
52 'enabled':True
@@ -67,7 +67,7 b' class LatexExporter(TemplateExporter):'
67 def default_config(self):
67 def default_config(self):
68 c = Config({
68 c = Config({
69 'NbConvertBase': {
69 'NbConvertBase': {
70 'display_data_priority' : ['latex', 'application/pdf', 'png', 'jpg', 'svg', 'jpeg', 'text']
70 'display_data_priority' : ['text/latex', 'application/pdf', 'image/png', 'image/jpeg', 'image/svg+xml', 'text/plain']
71 },
71 },
72 'ExtractOutputPreprocessor': {
72 'ExtractOutputPreprocessor': {
73 'enabled':True
73 'enabled':True
@@ -4,13 +4,13 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from .exporter import Exporter
6 from .exporter import Exporter
7 from IPython.nbformat import current as nbformat
7 from IPython import nbformat
8 from IPython.utils.traitlets import Enum
8 from IPython.utils.traitlets import Enum
9
9
10 class NotebookExporter(Exporter):
10 class NotebookExporter(Exporter):
11 """Exports to an IPython notebook."""
11 """Exports to an IPython notebook."""
12
12
13 nbformat_version = Enum(list(range(2, nbformat.current_nbformat + 1)),
13 nbformat_version = Enum(list(nbformat.versions),
14 default_value=nbformat.current_nbformat,
14 default_value=nbformat.current_nbformat,
15 config=True,
15 config=True,
16 help="""The nbformat version to write.
16 help="""The nbformat version to write.
@@ -24,7 +24,7 b' class NotebookExporter(Exporter):'
24
24
25 def from_notebook_node(self, nb, resources=None, **kw):
25 def from_notebook_node(self, nb, resources=None, **kw):
26 nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw)
26 nb_copy, resources = super(NotebookExporter, self).from_notebook_node(nb, resources, **kw)
27 if self.nbformat_version != nbformat.current_nbformat:
27 if self.nbformat_version != nb_copy.nbformat:
28 resources['output_suffix'] = '.v%i' % self.nbformat_version
28 resources['output_suffix'] = '.v%i' % self.nbformat_version
29 else:
29 else:
30 resources['output_suffix'] = '.nbconvert'
30 resources['output_suffix'] = '.nbconvert'
@@ -199,7 +199,7 b' class TemplateExporter(Exporter):'
199
199
200 Parameters
200 Parameters
201 ----------
201 ----------
202 nb : :class:`~IPython.nbformat.current.NotebookNode`
202 nb : :class:`~IPython.nbformat.NotebookNode`
203 Notebook node
203 Notebook node
204 resources : dict
204 resources : dict
205 Additional resources that can be accessed read/write by
205 Additional resources that can be accessed read/write by
@@ -1,177 +1,262 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": "notebook2"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "markdown",
10 {
5 "metadata": {},
11 "cell_type": "heading",
6 "source": [
12 "level": 1,
7 "# NumPy and Matplotlib examples"
13 "metadata": {},
8 ]
14 "source": [
9 },
15 "NumPy and Matplotlib examples"
10 {
16 ]
11 "cell_type": "markdown",
17 },
12 "metadata": {},
18 {
13 "source": [
19 "cell_type": "markdown",
14 "First import NumPy and Matplotlib:"
20 "metadata": {},
15 ]
21 "source": [
16 },
22 "First import NumPy and Matplotlib:"
17 {
23 ]
18 "cell_type": "code",
24 },
19 "execution_count": 1,
25 {
20 "metadata": {
26 "cell_type": "code",
21 "collapsed": false
27 "collapsed": false,
22 },
28 "input": [
23 "outputs": [
29 "%pylab inline"
30 ],
31 "language": "python",
32 "metadata": {},
33 "outputs": [
34 {
35 "output_type": "stream",
36 "stream": "stdout",
37 "text": [
38 "\n",
39 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
40 "For more information, type 'help(pylab)'.\n"
41 ]
42 }
43 ],
44 "prompt_number": 1
45 },
46 {
47 "cell_type": "code",
48 "collapsed": false,
49 "input": [
50 "import numpy as np"
51 ],
52 "language": "python",
53 "metadata": {},
54 "outputs": [],
55 "prompt_number": 2
56 },
57 {
24 {
58 "cell_type": "markdown",
25 "name": "stdout",
59 "metadata": {},
26 "output_type": "stream",
60 "source": [
27 "text": [
61 "Now we show some very basic examples of how they can be used."
28 "\n",
29 "Welcome to pylab, a matplotlib-based Python environment [backend: module://IPython.kernel.zmq.pylab.backend_inline].\n",
30 "For more information, type 'help(pylab)'.\n"
62 ]
31 ]
63 },
32 }
64 {
33 ],
65 "cell_type": "code",
34 "source": [
66 "collapsed": false,
35 "%pylab inline"
67 "input": [
36 ]
68 "a = np.random.uniform(size=(100,100))"
37 },
69 ],
38 {
70 "language": "python",
39 "cell_type": "code",
71 "metadata": {},
40 "execution_count": 2,
72 "outputs": [],
41 "metadata": {
73 "prompt_number": 6
42 "collapsed": false
74 },
43 },
75 {
44 "outputs": [],
76 "cell_type": "code",
45 "source": [
77 "collapsed": false,
46 "import numpy as np"
78 "input": [
47 ]
79 "a.shape"
48 },
80 ],
49 {
81 "language": "python",
50 "cell_type": "markdown",
82 "metadata": {},
51 "metadata": {},
83 "outputs": [
52 "source": [
84 {
53 "Now we show some very basic examples of how they can be used."
85 "metadata": {},
54 ]
86 "output_type": "pyout",
55 },
87 "prompt_number": 7,
56 {
88 "text": [
57 "cell_type": "code",
89 "(100, 100)"
58 "execution_count": 6,
90 ]
59 "metadata": {
91 }
60 "collapsed": false
92 ],
61 },
93 "prompt_number": 7
62 "outputs": [],
94 },
63 "source": [
95 {
64 "a = np.random.uniform(size=(100,100))"
96 "cell_type": "code",
65 ]
97 "collapsed": false,
66 },
98 "input": [
67 {
99 "evs = np.linalg.eigvals(a)"
68 "cell_type": "code",
100 ],
69 "execution_count": 7,
101 "language": "python",
70 "metadata": {
102 "metadata": {},
71 "collapsed": false
103 "outputs": [],
72 },
104 "prompt_number": 8
73 "outputs": [
105 },
106 {
74 {
107 "cell_type": "code",
75 "data": {
108 "collapsed": false,
76 "text/plain": [
109 "input": [
77 "(100, 100)"
110 "evs.shape"
78 ]
111 ],
79 },
112 "language": "python",
80 "execution_count": 7,
113 "metadata": {},
81 "metadata": {},
114 "outputs": [
82 "output_type": "execute_result"
115 {
83 }
116 "metadata": {},
84 ],
117 "output_type": "pyout",
85 "source": [
118 "prompt_number": 10,
86 "a.shape"
119 "text": [
87 ]
120 "(100,)"
88 },
121 ]
89 {
122 }
90 "cell_type": "code",
123 ],
91 "execution_count": 8,
124 "prompt_number": 10
92 "metadata": {
125 },
93 "collapsed": false
94 },
95 "outputs": [],
96 "source": [
97 "evs = np.linalg.eigvals(a)"
98 ]
99 },
100 {
101 "cell_type": "code",
102 "execution_count": 10,
103 "metadata": {
104 "collapsed": false
105 },
106 "outputs": [
126 {
107 {
127 "cell_type": "markdown",
108 "data": {
109 "text/plain": [
110 "(100,)"
111 ]
112 },
113 "execution_count": 10,
128 "metadata": {},
114 "metadata": {},
129 "source": [
115 "output_type": "execute_result"
130 "Here is a cell that has both text and PNG output:"
116 }
131 ]
117 ],
132 },
118 "source": [
119 "evs.shape"
120 ]
121 },
122 {
123 "cell_type": "markdown",
124 "metadata": {},
125 "source": [
126 "Here is a cell that has both text and PNG output:"
127 ]
128 },
129 {
130 "cell_type": "code",
131 "execution_count": 14,
132 "metadata": {
133 "collapsed": false
134 },
135 "outputs": [
133 {
136 {
134 "cell_type": "code",
137 "data": {
135 "collapsed": false,
138 "text/plain": [
136 "input": [
139 "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
137 "hist(evs.real)"
140 " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n",
138 ],
141 " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n",
139 "language": "python",
142 " 39.42458533, 44.71961607, 50.01464682]),\n",
143 " <a list of 10 Patch objects>)"
144 ]
145 },
146 "execution_count": 14,
140 "metadata": {},
147 "metadata": {},
141 "outputs": [
148 "output_type": "execute_result"
142 {
143 "metadata": {},
144 "output_type": "pyout",
145 "prompt_number": 14,
146 "text": [
147 "(array([95, 4, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
148 " array([ -2.93566063, 2.35937011, 7.65440086, 12.9494316 ,\n",
149 " 18.24446235, 23.53949309, 28.83452384, 34.12955458,\n",
150 " 39.42458533, 44.71961607, 50.01464682]),\n",
151 " <a list of 10 Patch objects>)"
152 ]
153 },
154 {
155 "metadata": {},
156 "output_type": "display_data",
157 "png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\nOqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\ndbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\nCDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\nkZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\nBBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\ny3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\nAEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\nGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\nA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\ncFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\nisVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\nlhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\nW7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\nTTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\nGP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\nPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\nisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\nNWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\nT0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\nwJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\nTitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\nli1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\n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\n",
158 "text": [
159 "<matplotlib.figure.Figure at 0x108c8f1d0>"
160 ]
161 }
162 ],
163 "prompt_number": 14
164 },
149 },
165 {
150 {
166 "cell_type": "code",
151 "data": {
167 "collapsed": false,
152 "image/png": [
168 "input": [],
153 "iVBORw0KGgoAAAANSUhEUgAAAXgAAAD9CAYAAAC2l2x5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
169 "language": "python",
154 "AAALEgAACxIB0t1+/AAAEhdJREFUeJzt3X1olfX/x/HXtVbT8CZDmsK6KmrubEu3U2xnZOpxLBnG\n",
155 "OqsIE7RoE3QRZkT/yEAjcIh/LIs6i/BEGSU1CkxT0+pkFp1zMmsxZ5uUTIXoxm95lmdlef3+8Nep\n",
156 "dbtz7exs16fnAw7sXNs5n/c14nmurl3naDmO4wgAYJy8sR4AADA6CDwAGIrAA4ChCDwAGIrAA4Ch\n",
157 "CDwAGOofA9/U1KTCwkLNnj07vS2ZTCoUCsm2bTU2NmpgYCD9vccee0zFxcUqKyvTgQMHRm9qAMC/\n",
158 "+sfA33PPPdq9e/eQbeFwWLZtq6+vT0VFRero6JAkffXVV3ryySf15ptvKhwOa/Xq1aM3NQDgX/1j\n",
159 "4OfNm6dp06YN2RaPx9Xc3KyCggI1NTUpFotJkmKxmOrr62XbthYsWCDHcZRMJkdvcgDAP8r4HHwi\n",
160 "kZDP55Mk+Xw+xeNxSecDX1pamv65kpKS9PcAALmXn+kDMvlkA8uyhrUNAPDvMv1kmYyP4KuqqtTT\n",
161 "0yNJ6unpUVVVlSQpEAjo8OHD6Z87cuRI+nt/NaRXb+vWrRvzGZh/7Odgfu/dvDy747j7yLCMAx8I\n",
162 "BBSJRJRKpRSJRFRTUyNJqq6u1p49e9Tf369oNKq8vDxNnjzZ1VAAgJH7x8AvXbpUN9xwg3p7e3X5\n",
163 "5ZfrmWeeUUtLi/r7+1VSUqKTJ09q1apVkqTCwkK1tLSotrZW9957rzZv3pyTHQAA/DXLcXvs73ZB\n",
164 "y3L9vxvjQTQaVTAYHOsxXGP+scX8Y8fLs0vu2kngAcAD3LSTjyoAAEMReAAwFIEHAEMReAAwFIEH\n",
165 "AEP9ZwM/Zcqlsixr1G9Tplw61rsK4D/qP3uZ5PnPxMnFHONjfwF4G5dJAgDSCDwAGIrAA4ChCDwA\n",
166 "GIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\n",
167 "A4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChXAf+6aef1g03\n",
168 "3KDrr79ea9askSQlk0mFQiHZtq3GxkYNDAxkbVAAQGZcBf7UqVPasGGD9u7dq0Qiod7eXu3Zs0fh\n",
169 "cFi2bauvr09FRUXq6OjI9rwAgGFyFfiJEyfKcRx9//33SqVSOnPmjC655BLF43E1NzeroKBATU1N\n",
170 "isVi2Z4XADBMrgMfDod15ZVXasaMGZo7d64CgYASiYR8Pp8kyefzKR6PZ3VYAMDw5bt50Ndff62W\n",
171 "lhYdPnxY06ZN0x133KEdO3bIcZxhPX79+vXpr4PBoILBoJsxAMBY0WhU0Wh0RM9hOcOt8u/s3LlT\n",
172 "W7du1bZt2yRJ4XBYx44d09GjR9Xa2iq/36+DBw+qra1NnZ2dQxe0rGG/EIwmy7Ik5WKO8bG/ALzN\n",
173 "TTtdnaKZN2+ePvzwQ506dUo//vijdu3apUWLFikQCCgSiSiVSikSiaimpsbN0wMAssBV4KdMmaLW\n",
174 "1lbdeuutuvHGG1VRUaGFCxeqpaVF/f39Kikp0cmTJ7Vq1apszwsAGCZXp2hGtCCnaAAgYzk7RQMA\n",
175 "GP8IPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEI\n",
176 "PAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAY\n",
177 "isADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYisADgKEIPAAYynXgf/jhB919992a\n",
178 "NWuWysrKFIvFlEwmFQqFZNu2GhsbNTAwkM1ZAQAZcB34devWybZtdXV1qaurSz6fT+FwWLZtq6+v\n",
179 "T0VFRero6MjmrACADLgO/L59+7R27VpNmDBB+fn5mjp1quLxuJqbm1VQUKCmpibFYrFszgoAyICr\n",
180 "wJ84cUKDg4NqaWlRIBDQxo0blUqllEgk5PP5JEk+n0/xeDyrwwIAhi/fzYMGBwfV29urTZs2qa6u\n",
181 "TitXrtRLL70kx3GG9fj169envw4GgwoGg27GAABjRaNRRaPRET2H5Qy3yn9QWlqqnp4eSdKuXbv0\n",
182 "3HPP6aefflJra6v8fr8OHjyotrY2dXZ2Dl3Qsob9QjCaLMuSlIs5xsf+AvA2N+10fQ6+uLhYsVhM\n",
183 "586d086dO1VXV6dAIKBIJKJUKqVIJKKamhq3Tw8AGCHXR/C9vb266667NDg4qLq6Oj388MM6d+6c\n",
184 "li1bpkOHDum6667T888/r0mTJg1dkCN4AMiYm3a6DrxbBB4AMpfTUzQAgPGNwAOAoQg8ABiKwAOA\n",
185 "oQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8\n",
186 "ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiK\n",
187 "wAOAoQg8ABiKwAOAoQg8ABiKwAOAoQg8ABiKwAOAoVwH/pdffpHf71dDQ4MkKZlMKhQKybZtNTY2\n",
188 "amBgIGtDAgAy5zrwmzdvVllZmSzLkiSFw2HZtq2+vj4VFRWpo6Mja0MCADLnKvAnTpzQ66+/rhUr\n",
189 "VshxHElSPB5Xc3OzCgoK1NTUpFgsltVBAQCZcRX4Bx54QJs2bVJe3m8PTyQS8vl8kiSfz6d4PJ6d\n",
190 "CQEAruRn+oAdO3bosssuk9/vVzQaTW//9Uh+ONavX5/+OhgMKhgMZjoGABgtGo0OaawblpNJmSWt\n",
191 "XbtWW7duVX5+vgYHB3X69GnddtttOnPmjFpbW+X3+3Xw4EG1tbWps7PzzwtaVkYvBqPl/N8OcjHH\n",
192 "+NhfAN7mpp0Zn6LZsGGDjh8/ri+++ELbtm1TbW2ttm7dqkAgoEgkolQqpUgkopqamkyfGgCQRSO+\n",
193 "Dv7Xq2haWlrU39+vkpISnTx5UqtWrRrxcAAA9zI+RTPiBTlFAwAZy8kpGgCANxB4ADAUgQcAQxF4\n",
194 "ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAU\n",
195 "gQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcA\n",
196 "QxF4ADAUgQcAQxF4ADAUgQcAQxF4ADAUgQcAQ7kK/PHjx7Vw4UKVl5crGAzqhRdekCQlk0mFQiHZ\n",
197 "tq3GxkYNDAxkdVgAwPC5CvyFF16o9vZ2dXd3q7OzU62trUomkwqHw7JtW319fSoqKlJHR0e25wUA\n",
198 "DJOrwM+YMUOVlZWSpOnTp6u8vFyJRELxeFzNzc0qKChQU1OTYrFYVocFAAzfiM/BHz16VN3d3aqu\n",
199 "rlYikZDP55Mk+Xw+xePxEQ8IAHAnfyQPTiaTWrJkidrb2zVp0iQ5jjOsx61fvz79dTAYVDAYHMkY\n",
200 "AGCcaDSqaDQ6ouewnOFW+Q/Onj2rm2++WYsXL9aaNWskSbfffrtaW1vl9/t18OBBtbW1qbOzc+iC\n",
201 "ljXsF4LRZFmWpFzMMT72F4C3uWmnq1M0juOoublZ1157bTrukhQIBBSJRJRKpRSJRFRTU+Pm6QEA\n",
202 "WeDqCP7AgQOaP3++5syZ8/9HwlJbW5vmzp2rZcuW6dChQ7ruuuv0/PPPa9KkSUMX5AgeADLmpp2u\n",
203 "T9G4ReABIHM5O0UDABj/CDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrA\n",
204 "A4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4Ch\n",
205 "CDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4ChCDwAGIrAA4Ch8sd6APPly7KsUV1h8uRpOn361Kiu\n",
206 "AcB7LMdxnJwuaFnK8ZJ/O4eUizlysc74+J0CGD1u2skpGgAwFIEHAEMReAAwVNYDv3//fpWWlqq4\n",
207 "uFiPP/54tp9+HIiO9QAjEo1Gx3qEEWH+seXl+b08u1tZD/z999+vp556Svv27dMTTzyhb775JttL\n",
208 "jLHoWA8wIl7/j5z5x5aX5/fy7G5lNfDff/+9JGn+/Pm64oortGjRIsVisWwuAcBAU6ZcKsuyRvXW\n",
209 "1rZxrHcz57Ia+EQiIZ/Pl75fVlamDz74IJtLADBQMvk/nb+cePRuP/00mLsdGieyeh38vn37tGXL\n",
210 "Fr344ouSpI6ODp08eVKPPPLIbwuO8pt+AMBUmeY6q+9kraqq0kMPPZS+393drfr6+iE/wxtyACA3\n",
211 "snqKZurUqZLOX0lz7Ngx7d27V4FAIJtLAACGKeufRfPoo49q5cqVOnv2rFavXq3p06dnewkAwDBk\n",
212 "/TLJBQsWqKenR0ePHtXq1aslSS+//LLKy8t1wQUX6KOPPhry84899piKi4tVVlamAwcOZHucrPHa\n",
213 "9f1NTU0qLCzU7Nmz09uSyaRCoZBs21ZjY6MGBgbGcMJ/dvz4cS1cuFDl5eUKBoN64YUXJHlnHwYH\n",
214 "BxUIBFRZWamamhq1t7dL8s78kvTLL7/I7/eroaFBkrdmv/LKKzVnzhz5/X5VV1dL8tb8P/zwg+6+\n",
215 "+27NmjVLZWVlisVirubPyTtZZ8+erVdffVXz588fsv2rr77Sk08+qTfffFPhcDj9gjAeee36/nvu\n",
216 "uUe7d+8esi0cDsu2bfX19amoqEgdHR1jNN2/u/DCC9Xe3q7u7m51dnaqtbVVyWTSM/swYcIEvf32\n",
217 "2/r444/1zjvvaMuWLerr6/PM/JK0efNmlZWVpS+M8NLslmUpGo3q0KFDisfjkrw1/7p162Tbtrq6\n",
218 "utTV1SWfz+dq/pwE3ufzadasWX/aHovFVF9fL9u2tWDBAjmOo2QymYuRMuLF6/vnzZunadOmDdkW\n",
219 "j8fV3NysgoICNTU1jet9mDFjhiorKyVJ06dPV3l5uRKJhKf24eKLL5YkDQwM6Oeff1ZBQYFn5j9x\n",
220 "4oRef/11rVixIn1hhFdm/9UfL+jw0vz79u3T2rVrNWHCBOXn52vq1Kmu5h/Tz6KJx+MqLS1N3y8p\n",
221 "KUm/2o4nplzf//v98Pl84/J3/VeOHj2q7u5uVVdXe2ofzp07p4qKChUWFuq+++6Tbduemf+BBx7Q\n",
222 "pk2blJf3WyK8Mrt0/gi+trZWjY2N2r59uyTvzH/ixAkNDg6qpaVFgUBAGzduVCqVcjV/1v7IetNN\n",
223 "N+nLL7/80/YNGzakz+H90V9dMsl18qPHi5eoJpNJLVmyRO3t7Zo0aZKn9iEvL0+ffPKJjh07psWL\n",
224 "F2vu3LmemH/Hjh267LLL5Pf7h7y93wuz/+q9997TzJkz1dPTo4aGBlVXV3tm/sHBQfX29mrTpk2q\n",
225 "q6vTypUr9dJLL7maP2tH8Hv37tWnn376p9vfxV2SAoGADh8+nL5/5MgRVVVVZWukrKmqqtKRI0fS\n",
226 "97u7u1VTUzOGE7lTVVWlnp4eSVJPT8+4/F3/3tmzZ3X77bdr+fLlCoVCkry3D9L5P/gtXrxYsVjM\n",
227 "E/O///772r59u6666iotXbpUb731lpYvX+6J2X81c+ZMSVJpaaluueUWvfbaa56Z/5prrlFJSYka\n",
228 "Gho0ceJELV26VLt373Y1f85P0fz+Vai6ulp79uxRf3+/otGo8vLyNHny5FyP9K9Mub4/EAgoEoko\n",
229 "lUopEomM6xcpx3HU3Nysa6+9VmvWrElv98o+fPPNN/ruu+8kSd9++63eeOMNhUIhT8y/YcMGHT9+\n",
230 "XF988YW2bdum2tpabd261ROzS9KZM2fSf8v7+uuvtWfPHtXX13tmfkkqLi5WLBbTuXPntHPnTtXV\n",
231 "1bmb38mBV155xSkqKnImTJjgFBYWOvX19envPfroo87VV1/tlJaWOvv378/FOK5Eo1HH5/M5V199\n",
232 "tbN58+axHudf3Xnnnc7MmTOdiy66yCkqKnIikYhz+vRp55ZbbnEuv/xyJxQKOclkcqzH/Fvvvvuu\n",
233 "Y1mWU1FR4VRWVjqVlZXOrl27PLMPXV1djt/vd+bMmeMsWrTIefbZZx3HcTwz/6+i0ajT0NDgOI53\n",
234 "Zv/888+diooKp6KiwqmtrXW2bNniOI535nccx/nss8+cQCDgVFRUOA8++KAzMDDgav6c/5usAIDc\n",
235 "4F90AgBDEXgAMBSBBwBDEXgAMBSBBwBDEXgAMNT/AQKseNIf7mhWAAAAAElFTkSuQmCC\n"
236 ],
237 "text/plain": [
238 "<matplotlib.figure.Figure at 0x108c8f1d0>"
239 ]
240 },
170 "metadata": {},
241 "metadata": {},
171 "outputs": []
242 "output_type": "display_data"
172 }
243 }
173 ],
244 ],
174 "metadata": {}
245 "source": [
246 "hist(evs.real)"
247 ]
248 },
249 {
250 "cell_type": "code",
251 "execution_count": null,
252 "metadata": {
253 "collapsed": false
254 },
255 "outputs": [],
256 "source": []
175 }
257 }
176 ]
258 ],
259 "metadata": {},
260 "nbformat": 4,
261 "nbformat_minor": 0
177 } No newline at end of file
262 }
@@ -1,84 +1,77 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "raw",
10 {
5 "metadata": {
11 "cell_type": "raw",
6 "raw_mimetype": "text/html"
12 "metadata": {
7 },
13 "raw_mimetype": "text/html"
8 "source": [
14 },
9 "<b>raw html</b>"
15 "source": [
10 ]
16 "<b>raw html</b>"
11 },
17 ]
12 {
18 },
13 "cell_type": "raw",
19 {
14 "metadata": {
20 "cell_type": "raw",
15 "raw_mimetype": "text/markdown"
21 "metadata": {
16 },
22 "raw_mimetype": "text/markdown"
17 "source": [
23 },
18 "* raw markdown\n",
24 "source": [
19 "* bullet\n",
25 "* raw markdown\n",
20 "* list"
26 "* bullet\n",
21 ]
27 "* list"
22 },
28 ]
23 {
29 },
24 "cell_type": "raw",
30 {
25 "metadata": {
31 "cell_type": "raw",
26 "raw_mimetype": "text/restructuredtext"
32 "metadata": {
27 },
33 "raw_mimetype": "text/restructuredtext"
28 "source": [
34 },
29 "``raw rst``\n",
35 "source": [
30 "\n",
36 "``raw rst``\n",
31 ".. sourcecode:: python\n",
37 "\n",
32 "\n",
38 ".. sourcecode:: python\n",
33 " def foo(): pass\n"
39 "\n",
34 ]
40 " def foo(): pass\n"
35 },
41 ]
36 {
42 },
37 "cell_type": "raw",
43 {
38 "metadata": {
44 "cell_type": "raw",
39 "raw_mimetype": "text/x-python"
45 "metadata": {
40 },
46 "raw_mimetype": "text/x-python"
41 "source": [
47 },
42 "def bar():\n",
48 "source": [
43 " \"\"\"raw python\"\"\"\n",
49 "def bar():\n",
44 " pass"
50 " \"\"\"raw python\"\"\"\n",
45 ]
51 " pass"
46 },
52 ]
47 {
53 },
48 "cell_type": "raw",
54 {
49 "metadata": {
55 "cell_type": "raw",
50 "raw_mimetype": "text/latex"
56 "metadata": {
51 },
57 "raw_mimetype": "text/latex"
52 "source": [
58 },
53 "\\LaTeX\n",
59 "source": [
54 "% raw latex"
60 "\\LaTeX\n",
55 ]
61 "% raw latex"
56 },
62 ]
57 {
63 },
58 "cell_type": "raw",
64 {
59 "metadata": {},
65 "cell_type": "raw",
60 "source": [
66 "metadata": {},
61 "# no raw_mimetype metadata, should be included by default"
67 "source": [
62 ]
68 "# no raw_mimetype metadata, should be included by default"
63 },
69 ]
64 {
70 },
65 "cell_type": "raw",
71 {
66 "metadata": {
72 "cell_type": "raw",
67 "raw_mimetype": "doesnotexist"
73 "metadata": {
68 },
74 "raw_mimetype": "doesnotexist"
69 "source": [
75 },
70 "garbage format defined, should never be included"
76 "source": [
71 ]
77 "garbage format defined, should never be included"
78 ]
79 }
80 ],
81 "metadata": {}
82 }
72 }
83 ]
73 ],
84 }
74 "metadata": {},
75 "nbformat": 4,
76 "nbformat_minor": 0
77 } No newline at end of file
@@ -2,29 +2,17 b''
2 Module with tests for export.py
2 Module with tests for export.py
3 """
3 """
4
4
5 #-----------------------------------------------------------------------------
5 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
7
17 import os
8 import os
18
9
19 from IPython.nbformat import current as nbformat
10 from IPython import nbformat
20
11
21 from .base import ExportersTestsBase
12 from .base import ExportersTestsBase
22 from ..export import *
13 from ..export import *
23 from ..python import PythonExporter
14 from ..python import PythonExporter
24
15
25 #-----------------------------------------------------------------------------
26 # Class
27 #-----------------------------------------------------------------------------
28
16
29 class TestExport(ExportersTestsBase):
17 class TestExport(ExportersTestsBase):
30 """Contains test functions for export.py"""
18 """Contains test functions for export.py"""
@@ -53,7 +41,7 b' class TestExport(ExportersTestsBase):'
53 Can a notebook be exported by a notebook node handle?
41 Can a notebook be exported by a notebook node handle?
54 """
42 """
55 with open(self._get_notebook(), 'r') as f:
43 with open(self._get_notebook(), 'r') as f:
56 notebook = nbformat.read(f, 'json')
44 notebook = nbformat.read(f, 4)
57 (output, resources) = export_by_name('python', notebook)
45 (output, resources) = export_by_name('python', notebook)
58 assert len(output) > 0
46 assert len(output) > 0
59
47
@@ -9,7 +9,8 b' import re'
9
9
10 from .base import ExportersTestsBase
10 from .base import ExportersTestsBase
11 from ..latex import LatexExporter
11 from ..latex import LatexExporter
12 from IPython.nbformat import current
12 from IPython.nbformat import write
13 from IPython.nbformat import v4
13 from IPython.testing.decorators import onlyif_cmds_exist
14 from IPython.testing.decorators import onlyif_cmds_exist
14 from IPython.utils.tempdir import TemporaryDirectory
15 from IPython.utils.tempdir import TemporaryDirectory
15
16
@@ -85,20 +86,18 b' class TestLatexExporter(ExportersTestsBase):'
85 large_lorem_ipsum_text = "".join([lorem_ipsum_text]*3000)
86 large_lorem_ipsum_text = "".join([lorem_ipsum_text]*3000)
86
87
87 notebook_name = "lorem_ipsum_long.ipynb"
88 notebook_name = "lorem_ipsum_long.ipynb"
88 nb = current.new_notebook(
89 nb = v4.new_notebook(
89 worksheets=[
90 cells=[
90 current.new_worksheet(cells=[
91 v4.new_markdown_cell(source=large_lorem_ipsum_text)
91 current.new_text_cell('markdown',source=large_lorem_ipsum_text)
92 ])
93 ]
92 ]
94 )
93 )
95
94
96 with TemporaryDirectory() as td:
95 with TemporaryDirectory() as td:
97 nbfile = os.path.join(td, notebook_name)
96 nbfile = os.path.join(td, notebook_name)
98 with open(nbfile, 'w') as f:
97 with open(nbfile, 'w') as f:
99 current.write(nb, f, 'ipynb')
98 write(nb, f, 4)
100
99
101 (output, resources) = LatexExporter(template_file='article').from_filename(nbfile)
100 (output, resources) = LatexExporter(template_file='article').from_filename(nbfile)
102 assert len(output) > 0
101 assert len(output) > 0
103
102
104 @onlyif_cmds_exist('pandoc')
103 @onlyif_cmds_exist('pandoc')
@@ -8,6 +8,7 b' import json'
8 from .base import ExportersTestsBase
8 from .base import ExportersTestsBase
9 from ..notebook import NotebookExporter
9 from ..notebook import NotebookExporter
10
10
11 from IPython.nbformat import validate
11 from IPython.testing.tools import assert_big_text_equal
12 from IPython.testing.tools import assert_big_text_equal
12
13
13 class TestNotebookExporter(ExportersTestsBase):
14 class TestNotebookExporter(ExportersTestsBase):
@@ -29,7 +30,7 b' class TestNotebookExporter(ExportersTestsBase):'
29 exporter = self.exporter_class(nbformat_version=3)
30 exporter = self.exporter_class(nbformat_version=3)
30 (output, resources) = exporter.from_filename(self._get_notebook())
31 (output, resources) = exporter.from_filename(self._get_notebook())
31 nb = json.loads(output)
32 nb = json.loads(output)
32 self.assertEqual(nb['nbformat'], 3)
33 validate(nb)
33
34
34 def test_downgrade_2(self):
35 def test_downgrade_2(self):
35 exporter = self.exporter_class(nbformat_version=2)
36 exporter = self.exporter_class(nbformat_version=2)
@@ -1,28 +1,17 b''
1 """Tests for RSTExporter"""
1 """Tests for RSTExporter"""
2
2
3 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
5
15 import io
6 import io
16
7
17 from IPython.nbformat import current
8 from IPython import nbformat
9 from IPython.nbformat import v4
18
10
19 from .base import ExportersTestsBase
11 from .base import ExportersTestsBase
20 from ..rst import RSTExporter
12 from ..rst import RSTExporter
21 from IPython.testing.decorators import onlyif_cmds_exist
13 from IPython.testing.decorators import onlyif_cmds_exist
22
14
23 #-----------------------------------------------------------------------------
24 # Class
25 #-----------------------------------------------------------------------------
26
15
27 class TestRSTExporter(ExportersTestsBase):
16 class TestRSTExporter(ExportersTestsBase):
28 """Tests for RSTExporter"""
17 """Tests for RSTExporter"""
@@ -50,14 +39,14 b' class TestRSTExporter(ExportersTestsBase):'
50 """No empty code cells in rst"""
39 """No empty code cells in rst"""
51 nbname = self._get_notebook()
40 nbname = self._get_notebook()
52 with io.open(nbname, encoding='utf8') as f:
41 with io.open(nbname, encoding='utf8') as f:
53 nb = current.read(f, 'json')
42 nb = nbformat.read(f, 4)
54
43
55 exporter = self.exporter_class()
44 exporter = self.exporter_class()
56
45
57 (output, resources) = exporter.from_notebook_node(nb)
46 (output, resources) = exporter.from_notebook_node(nb)
58 # add an empty code cell
47 # add an empty code cell
59 nb.worksheets[0].cells.append(
48 nb.cells.append(
60 current.new_code_cell(input="")
49 v4.new_code_cell(source="")
61 )
50 )
62 (output2, resources) = exporter.from_notebook_node(nb)
51 (output2, resources) = exporter.from_notebook_node(nb)
63 # adding an empty code cell shouldn't change output
52 # adding an empty code cell shouldn't change output
@@ -21,6 +21,7 b' from pygments.formatters import HtmlFormatter'
21 from pygments.util import ClassNotFound
21 from pygments.util import ClassNotFound
22
22
23 # IPython imports
23 # IPython imports
24 from IPython.nbconvert.filters.strings import add_anchor
24 from IPython.nbconvert.utils.pandoc import pandoc
25 from IPython.nbconvert.utils.pandoc import pandoc
25 from IPython.nbconvert.utils.exceptions import ConversionException
26 from IPython.nbconvert.utils.exceptions import ConversionException
26 from IPython.utils.decorators import undoc
27 from IPython.utils.decorators import undoc
@@ -146,6 +147,10 b' class IPythonRenderer(mistune.Renderer):'
146 formatter = HtmlFormatter()
147 formatter = HtmlFormatter()
147 return highlight(code, lexer, formatter)
148 return highlight(code, lexer, formatter)
148
149
150 def header(self, text, level, raw=None):
151 html = super(IPythonRenderer, self).header(text, level, raw=raw)
152 return add_anchor(html)
153
149 # Pass math through unaltered - mathjax does the rendering in the browser
154 # Pass math through unaltered - mathjax does the rendering in the browser
150 def block_math(self, text):
155 def block_math(self, text):
151 return '$$%s$$' % text
156 return '$$%s$$' % text
@@ -4,17 +4,9 b''
4 Contains a collection of useful string manipulation filters for use in Jinja
4 Contains a collection of useful string manipulation filters for use in Jinja
5 templates.
5 templates.
6 """
6 """
7 #-----------------------------------------------------------------------------
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
7
15 #-----------------------------------------------------------------------------
8 # Copyright (c) IPython Development Team.
16 # Imports
9 # Distributed under the terms of the Modified BSD License.
17 #-----------------------------------------------------------------------------
18
10
19 import os
11 import os
20 import re
12 import re
@@ -28,9 +20,6 b' from xml.etree import ElementTree'
28 from IPython.core.interactiveshell import InteractiveShell
20 from IPython.core.interactiveshell import InteractiveShell
29 from IPython.utils import py3compat
21 from IPython.utils import py3compat
30
22
31 #-----------------------------------------------------------------------------
32 # Functions
33 #-----------------------------------------------------------------------------
34
23
35 __all__ = [
24 __all__ = [
36 'wrap_text',
25 'wrap_text',
@@ -88,9 +77,9 b' def html2text(element):'
88
77
89
78
90 def add_anchor(html):
79 def add_anchor(html):
91 """Add an anchor-link to an html header tag
80 """Add an anchor-link to an html header
92
81
93 For use in heading cells
82 For use on markdown headings
94 """
83 """
95 try:
84 try:
96 h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8'))
85 h = ElementTree.fromstring(py3compat.cast_bytes_py2(html, encoding='utf-8'))
@@ -1,45 +1,26 b''
1 """
1 """Module with tests for DataTypeFilter"""
2 Module with tests for DataTypeFilter
3 """
4
2
5 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
17
5
18 from ...tests.base import TestsBase
6 from ...tests.base import TestsBase
19 from ..datatypefilter import DataTypeFilter
7 from ..datatypefilter import DataTypeFilter
20
8
21
9
22 #-----------------------------------------------------------------------------
23 # Class
24 #-----------------------------------------------------------------------------
25
26 class TestDataTypeFilter(TestsBase):
10 class TestDataTypeFilter(TestsBase):
27 """Contains test functions for datatypefilter.py"""
11 """Contains test functions for datatypefilter.py"""
28
12
29
30 def test_constructor(self):
13 def test_constructor(self):
31 """Can an instance of a DataTypeFilter be created?"""
14 """Can an instance of a DataTypeFilter be created?"""
32 DataTypeFilter()
15 DataTypeFilter()
33
16
34
35 def test_junk_types(self):
17 def test_junk_types(self):
36 """Can the DataTypeFilter pickout a useful type from a list of junk types?"""
18 """Can the DataTypeFilter pickout a useful type from a list of junk types?"""
37 filter = DataTypeFilter()
19 filter = DataTypeFilter()
38 assert "png" in filter(["hair", "water", "png", "rock"])
20 assert "image/png" in filter(["hair", "water", "image/png", "rock"])
39 assert "application/pdf" in filter(["application/pdf", "hair", "water", "png", "rock"])
21 assert "application/pdf" in filter(["application/pdf", "hair", "water", "png", "rock"])
40 self.assertEqual(filter(["hair", "water", "rock"]), [])
22 self.assertEqual(filter(["hair", "water", "rock"]), [])
41
23
42
43 def test_null(self):
24 def test_null(self):
44 """Will the DataTypeFilter fail if no types are passed in?"""
25 """Will the DataTypeFilter fail if no types are passed in?"""
45 filter = DataTypeFilter()
26 filter = DataTypeFilter()
@@ -1,3 +1,4 b''
1 # coding: utf-8
1 """Tests for conversions from markdown to other formats"""
2 """Tests for conversions from markdown to other formats"""
2
3
3 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
@@ -26,7 +27,8 b' class TestMarkdown(TestsBase):'
26 '#test',
27 '#test',
27 '##test',
28 '##test',
28 'test\n----',
29 'test\n----',
29 'test [link](https://google.com/)']
30 'test [link](https://google.com/)',
31 ]
30
32
31 tokens = [
33 tokens = [
32 '*test',
34 '*test',
@@ -39,7 +41,8 b' class TestMarkdown(TestsBase):'
39 'test',
41 'test',
40 'test',
42 'test',
41 'test',
43 'test',
42 ('test', 'https://google.com/')]
44 ('test', 'https://google.com/'),
45 ]
43
46
44
47
45 @dec.onlyif_cmds_exist('pandoc')
48 @dec.onlyif_cmds_exist('pandoc')
@@ -87,6 +90,17 b' class TestMarkdown(TestsBase):'
87 for index, test in enumerate(self.tests):
90 for index, test in enumerate(self.tests):
88 self._try_markdown(markdown2html, test, self.tokens[index])
91 self._try_markdown(markdown2html, test, self.tokens[index])
89
92
93 def test_markdown2html_heading_anchors(self):
94 for md, tokens in [
95 ('# test',
96 ('<h1', '>test', 'id="test"', u'&#182;</a>', "anchor-link")
97 ),
98 ('###test head space',
99 ('<h3', '>test head space', 'id="test-head-space"', u'&#182;</a>', "anchor-link")
100 )
101 ]:
102 self._try_markdown(markdown2html, md, tokens)
103
90 def test_markdown2html_math(self):
104 def test_markdown2html_math(self):
91 # Mathematical expressions should be passed through unaltered
105 # Mathematical expressions should be passed through unaltered
92 cases = [("\\begin{equation*}\n"
106 cases = [("\\begin{equation*}\n"
@@ -66,9 +66,8 b' class Preprocessor(NbConvertBase):'
66 Additional resources used in the conversion process. Allows
66 Additional resources used in the conversion process. Allows
67 preprocessors to pass variables into the Jinja engine.
67 preprocessors to pass variables into the Jinja engine.
68 """
68 """
69 for worksheet in nb.worksheets:
69 for index, cell in enumerate(nb.cells):
70 for index, cell in enumerate(worksheet.cells):
70 nb.cells[index], resources = self.preprocess_cell(cell, resources, index)
71 worksheet.cells[index], resources = self.preprocess_cell(cell, resources, index)
72 return nb, resources
71 return nb, resources
73
72
74
73
@@ -3,16 +3,8 b''
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 #-----------------------------------------------------------------------------
7 # Imports
8 #-----------------------------------------------------------------------------
9
10 from .base import Preprocessor
6 from .base import Preprocessor
11
7
12
13 #-----------------------------------------------------------------------------
14 # Classes
15 #-----------------------------------------------------------------------------
16 class ClearOutputPreprocessor(Preprocessor):
8 class ClearOutputPreprocessor(Preprocessor):
17 """
9 """
18 Removes the output from all code cells in a notebook.
10 Removes the output from all code cells in a notebook.
@@ -24,5 +16,5 b' class ClearOutputPreprocessor(Preprocessor):'
24 """
16 """
25 if cell.cell_type == 'code':
17 if cell.cell_type == 'code':
26 cell.outputs = []
18 cell.outputs = []
27 cell.prompt_number = None
19 cell.execution_count = None
28 return cell, resources
20 return cell, resources
@@ -4,6 +4,7 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import re
6 import re
7 from IPython.utils.log import get_logger
7
8
8 def cell_preprocessor(function):
9 def cell_preprocessor(function):
9 """
10 """
@@ -21,14 +22,11 b' def cell_preprocessor(function):'
21 """
22 """
22
23
23 def wrappedfunc(nb, resources):
24 def wrappedfunc(nb, resources):
24 from IPython.config import Application
25 get_logger().debug(
25 if Application.initialized():
26 Application.instance().log.debug(
27 "Applying preprocessor: %s", function.__name__
26 "Applying preprocessor: %s", function.__name__
28 )
27 )
29 for worksheet in nb.worksheets:
28 for index, cell in enumerate(nb.cells):
30 for index, cell in enumerate(worksheet.cells):
29 nb.cells[index], resources = function(cell, resources, index)
31 worksheet.cells[index], resources = function(cell, resources, index)
32 return nb, resources
30 return nb, resources
33 return wrappedfunc
31 return wrappedfunc
34
32
@@ -60,7 +58,7 b' def coalesce_streams(cell, resources, index):'
60 for output in outputs[1:]:
58 for output in outputs[1:]:
61 if (output.output_type == 'stream' and
59 if (output.output_type == 'stream' and
62 last.output_type == 'stream' and
60 last.output_type == 'stream' and
63 last.stream == output.stream
61 last.name == output.name
64 ):
62 ):
65 last.text += output.text
63 last.text += output.text
66
64
@@ -4,7 +4,6 b''
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 import os
6 import os
7 import sys
8
7
9 try:
8 try:
10 from queue import Empty # Py 3
9 from queue import Empty # Py 3
@@ -13,10 +12,11 b' except ImportError:'
13
12
14 from IPython.utils.traitlets import List, Unicode
13 from IPython.utils.traitlets import List, Unicode
15
14
16 from IPython.nbformat.current import reads, NotebookNode, writes
15 from IPython.nbformat.v4 import output_from_msg
17 from .base import Preprocessor
16 from .base import Preprocessor
18 from IPython.utils.traitlets import Integer
17 from IPython.utils.traitlets import Integer
19
18
19
20 class ExecutePreprocessor(Preprocessor):
20 class ExecutePreprocessor(Preprocessor):
21 """
21 """
22 Executes all the cells in a notebook
22 Executes all the cells in a notebook
@@ -25,25 +25,6 b' class ExecutePreprocessor(Preprocessor):'
25 timeout = Integer(30, config=True,
25 timeout = Integer(30, config=True,
26 help="The time to wait (in seconds) for output from executions."
26 help="The time to wait (in seconds) for output from executions."
27 )
27 )
28 # FIXME: to be removed with nbformat v4
29 # map msg_type to v3 output_type
30 msg_type_map = {
31 "error" : "pyerr",
32 "execute_result" : "pyout",
33 }
34
35 # FIXME: to be removed with nbformat v4
36 # map mime-type to v3 mime-type keys
37 mime_map = {
38 "text/plain" : "text",
39 "text/html" : "html",
40 "image/svg+xml" : "svg",
41 "image/png" : "png",
42 "image/jpeg" : "jpeg",
43 "text/latex" : "latex",
44 "application/json" : "json",
45 "application/javascript" : "javascript",
46 }
47
28
48 extra_arguments = List(Unicode)
29 extra_arguments = List(Unicode)
49
30
@@ -68,14 +49,14 b' class ExecutePreprocessor(Preprocessor):'
68 outputs = self.run_cell(self.kc.shell_channel, self.kc.iopub_channel, cell)
49 outputs = self.run_cell(self.kc.shell_channel, self.kc.iopub_channel, cell)
69 except Exception as e:
50 except Exception as e:
70 self.log.error("failed to run cell: " + repr(e))
51 self.log.error("failed to run cell: " + repr(e))
71 self.log.error(str(cell.input))
52 self.log.error(str(cell.source))
72 raise
53 raise
73 cell.outputs = outputs
54 cell.outputs = outputs
74 return cell, resources
55 return cell, resources
75
56
76 def run_cell(self, shell, iopub, cell):
57 def run_cell(self, shell, iopub, cell):
77 msg_id = shell.execute(cell.input)
58 msg_id = shell.execute(cell.source)
78 self.log.debug("Executing cell:\n%s", cell.input)
59 self.log.debug("Executing cell:\n%s", cell.source)
79 # wait for finish, with timeout
60 # wait for finish, with timeout
80 while True:
61 while True:
81 try:
62 try:
@@ -104,40 +85,27 b' class ExecutePreprocessor(Preprocessor):'
104 msg_type = msg['msg_type']
85 msg_type = msg['msg_type']
105 self.log.debug("output: %s", msg_type)
86 self.log.debug("output: %s", msg_type)
106 content = msg['content']
87 content = msg['content']
107 out = NotebookNode(output_type=self.msg_type_map.get(msg_type, msg_type))
108
88
109 # set the prompt number for the input and the output
89 # set the prompt number for the input and the output
110 if 'execution_count' in content:
90 if 'execution_count' in content:
111 cell['prompt_number'] = content['execution_count']
91 cell['execution_count'] = content['execution_count']
112 out.prompt_number = content['execution_count']
113
92
114 if msg_type == 'status':
93 if msg_type == 'status':
115 if content['execution_state'] == 'idle':
94 if content['execution_state'] == 'idle':
116 break
95 break
117 else:
96 else:
118 continue
97 continue
119 elif msg_type in {'execute_input', 'pyin'}:
98 elif msg_type == 'execute_input':
120 continue
99 continue
121 elif msg_type == 'clear_output':
100 elif msg_type == 'clear_output':
122 outs = []
101 outs = []
123 continue
102 continue
124
103
125 if msg_type == 'stream':
104 try:
126 out.stream = content['name']
105 out = output_from_msg(msg)
127 out.text = content['text']
106 except ValueError:
128 elif msg_type in ('display_data', 'execute_result'):
129 out['metadata'] = content['metadata']
130 for mime, data in content['data'].items():
131 # map mime-type keys to nbformat v3 keys
132 # this will be unnecessary in nbformat v4
133 key = self.mime_map.get(mime, mime)
134 out[key] = data
135 elif msg_type == 'error':
136 out.ename = content['ename']
137 out.evalue = content['evalue']
138 out.traceback = content['traceback']
139 else:
140 self.log.error("unhandled iopub msg: " + msg_type)
107 self.log.error("unhandled iopub msg: " + msg_type)
108 else:
109 outs.append(out)
141
110
142 outs.append(out)
143 return outs
111 return outs
@@ -1,17 +1,9 b''
1 """Module containing a preprocessor that extracts all of the outputs from the
1 """A preprocessor that extracts all of the outputs from the
2 notebook file. The extracted outputs are returned in the 'resources' dictionary.
2 notebook file. The extracted outputs are returned in the 'resources' dictionary.
3 """
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
4
12 #-----------------------------------------------------------------------------
5 # Copyright (c) IPython Development Team.
13 # Imports
6 # Distributed under the terms of the Modified BSD License.
14 #-----------------------------------------------------------------------------
15
7
16 import base64
8 import base64
17 import sys
9 import sys
@@ -22,9 +14,6 b' from IPython.utils.traitlets import Unicode, Set'
22 from .base import Preprocessor
14 from .base import Preprocessor
23 from IPython.utils import py3compat
15 from IPython.utils import py3compat
24
16
25 #-----------------------------------------------------------------------------
26 # Classes
27 #-----------------------------------------------------------------------------
28
17
29 class ExtractOutputPreprocessor(Preprocessor):
18 class ExtractOutputPreprocessor(Preprocessor):
30 """
19 """
@@ -35,7 +24,7 b' class ExtractOutputPreprocessor(Preprocessor):'
35 output_filename_template = Unicode(
24 output_filename_template = Unicode(
36 "{unique_key}_{cell_index}_{index}{extension}", config=True)
25 "{unique_key}_{cell_index}_{index}{extension}", config=True)
37
26
38 extract_output_types = Set({'png', 'jpeg', 'svg', 'application/pdf'}, config=True)
27 extract_output_types = Set({'image/png', 'image/jpeg', 'image/svg+xml', 'application/pdf'}, config=True)
39
28
40 def preprocess_cell(self, cell, resources, cell_index):
29 def preprocess_cell(self, cell, resources, cell_index):
41 """
30 """
@@ -64,14 +53,15 b' class ExtractOutputPreprocessor(Preprocessor):'
64
53
65 #Loop through all of the outputs in the cell
54 #Loop through all of the outputs in the cell
66 for index, out in enumerate(cell.get('outputs', [])):
55 for index, out in enumerate(cell.get('outputs', [])):
67
56 if out.output_type not in {'display_data', 'execute_result'}:
57 continue
68 #Get the output in data formats that the template needs extracted
58 #Get the output in data formats that the template needs extracted
69 for out_type in self.extract_output_types:
59 for mime_type in self.extract_output_types:
70 if out_type in out:
60 if mime_type in out.data:
71 data = out[out_type]
61 data = out.data[mime_type]
72
62
73 #Binary files are base64-encoded, SVG is already XML
63 #Binary files are base64-encoded, SVG is already XML
74 if out_type in {'png', 'jpeg', 'application/pdf'}:
64 if mime_type in {'image/png', 'image/jpeg', 'application/pdf'}:
75
65
76 # data is b64-encoded as text (str, unicode)
66 # data is b64-encoded as text (str, unicode)
77 # decodestring only accepts bytes
67 # decodestring only accepts bytes
@@ -82,14 +72,9 b' class ExtractOutputPreprocessor(Preprocessor):'
82 else:
72 else:
83 data = data.encode("UTF-8")
73 data = data.encode("UTF-8")
84
74
85 # Build an output name
75 ext = guess_extension(mime_type)
86 # filthy hack while we have some mimetype output, and some not
76 if ext is None:
87 if '/' in out_type:
77 ext = '.' + mime_type.rsplit('/')[-1]
88 ext = guess_extension(out_type)
89 if ext is None:
90 ext = '.' + out_type.rsplit('/')[-1]
91 else:
92 ext = '.' + out_type
93
78
94 filename = self.output_filename_template.format(
79 filename = self.output_filename_template.format(
95 unique_key=unique_key,
80 unique_key=unique_key,
@@ -97,13 +82,14 b' class ExtractOutputPreprocessor(Preprocessor):'
97 index=index,
82 index=index,
98 extension=ext)
83 extension=ext)
99
84
100 #On the cell, make the figure available via
85 # On the cell, make the figure available via
101 # cell.outputs[i].svg_filename ... etc (svg in example)
86 # cell.outputs[i].metadata.filenames['mime/type']
102 # Where
87 # where
103 # cell.outputs[i].svg contains the data
88 # cell.outputs[i].data['mime/type'] contains the data
104 if output_files_dir is not None:
89 if output_files_dir is not None:
105 filename = os.path.join(output_files_dir, filename)
90 filename = os.path.join(output_files_dir, filename)
106 out[out_type + '_filename'] = filename
91 out.metadata.setdefault('filenames', {})
92 out.metadata['filenames'][mime_type] = filename
107
93
108 #In the resources, make the figure available via
94 #In the resources, make the figure available via
109 # resources['outputs']['filename'] = data
95 # resources['outputs']['filename'] = data
@@ -4,17 +4,8 b' so that the appropriate highlighter can be used in the `highlight`'
4 filter.
4 filter.
5 """
5 """
6
6
7 #-----------------------------------------------------------------------------
7 # Copyright (c) IPython Development Team.
8 # Copyright (c) 2013, the IPython Development Team.
9 #
10 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
11 #
12 # The full license is in the file COPYING.txt, distributed with this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
9
19 from __future__ import print_function, absolute_import
10 from __future__ import print_function, absolute_import
20
11
@@ -24,10 +15,6 b' import re'
24 from .base import Preprocessor
15 from .base import Preprocessor
25 from IPython.utils.traitlets import Dict
16 from IPython.utils.traitlets import Dict
26
17
27 #-----------------------------------------------------------------------------
28 # Classes
29 #-----------------------------------------------------------------------------
30
31
18
32 class HighlightMagicsPreprocessor(Preprocessor):
19 class HighlightMagicsPreprocessor(Preprocessor):
33 """
20 """
@@ -106,8 +93,8 b' class HighlightMagicsPreprocessor(Preprocessor):'
106 """
93 """
107
94
108 # Only tag code cells
95 # Only tag code cells
109 if hasattr(cell, "input") and cell.cell_type == "code":
96 if cell.cell_type == "code":
110 magic_language = self.which_magic_language(cell.input)
97 magic_language = self.which_magic_language(cell.source)
111 if magic_language:
98 if magic_language:
112 cell['metadata']['magics_language'] = magic_language
99 cell['metadata']['magics_language'] = magic_language
113 return cell, resources
100 return cell, resources
@@ -1,23 +1,11 b''
1 """Module that pre-processes the notebook for export via Reveal.
1 """Module that pre-processes the notebook for export via Reveal."""
2 """
3 #-----------------------------------------------------------------------------
4 # Copyright (c) 2013, the IPython Development Team.
5 #
6 # Distributed under the terms of the Modified BSD License.
7 #
8 # The full license is in the file COPYING.txt, distributed with this software.
9 #-----------------------------------------------------------------------------
10
2
11 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
12 # Imports
4 # Distributed under the terms of the Modified BSD License.
13 #-----------------------------------------------------------------------------
14
5
15 from .base import Preprocessor
6 from .base import Preprocessor
16 from IPython.utils.traitlets import Unicode
7 from IPython.utils.traitlets import Unicode
17
8
18 #-----------------------------------------------------------------------------
19 # Classes and functions
20 #-----------------------------------------------------------------------------
21
9
22 class RevealHelpPreprocessor(Preprocessor):
10 class RevealHelpPreprocessor(Preprocessor):
23
11
@@ -43,31 +31,30 b' class RevealHelpPreprocessor(Preprocessor):'
43 preprocessors to pass variables into the Jinja engine.
31 preprocessors to pass variables into the Jinja engine.
44 """
32 """
45
33
46 for worksheet in nb.worksheets:
34 for index, cell in enumerate(nb.cells):
47 for index, cell in enumerate(worksheet.cells):
35
48
36 #Make sure the cell has slideshow metadata.
49 #Make sure the cell has slideshow metadata.
37 cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-')
50 cell.metadata.slide_type = cell.get('metadata', {}).get('slideshow', {}).get('slide_type', '-')
38
51
39 # Get the slide type. If type is start, subslide, or slide,
52 #Get the slide type. If type is start of subslide or slide,
40 # end the last subslide/slide.
53 #end the last subslide/slide.
41 if cell.metadata.slide_type in ['slide']:
54 if cell.metadata.slide_type in ['slide']:
42 nb.cells[index - 1].metadata.slide_helper = 'slide_end'
55 worksheet.cells[index - 1].metadata.slide_helper = 'slide_end'
43 if cell.metadata.slide_type in ['subslide']:
56 if cell.metadata.slide_type in ['subslide']:
44 nb.cells[index - 1].metadata.slide_helper = 'subslide_end'
57 worksheet.cells[index - 1].metadata.slide_helper = 'subslide_end'
45 # Prevent the rendering of "do nothing" cells before fragments
58 #Prevent the rendering of "do nothing" cells before fragments
46 # Group fragments passing frag_number to the data-fragment-index
59 #Group fragments passing frag_number to the data-fragment-index
47 if cell.metadata.slide_type in ['fragment']:
60 if cell.metadata.slide_type in ['fragment']:
48 nb.cells[index].metadata.frag_number = index
61 worksheet.cells[index].metadata.frag_number = index
49 i = 1
62 i = 1
50 while i < len(nb.cells) - index:
63 while i < len(worksheet.cells) - index:
51 nb.cells[index + i].metadata.frag_helper = 'fragment_end'
64 worksheet.cells[index + i].metadata.frag_helper = 'fragment_end'
52 nb.cells[index + i].metadata.frag_number = index
65 worksheet.cells[index + i].metadata.frag_number = index
53 i += 1
66 i += 1
54 # Restart the slide_helper when the cell status is changed
67 #Restart the slide_helper when the cell status is changed
55 # to other types.
68 #to other types.
56 if cell.metadata.slide_type in ['-', 'skip', 'notes', 'fragment']:
69 if cell.metadata.slide_type in ['-', 'skip', 'notes', 'fragment']:
57 nb.cells[index - 1].metadata.slide_helper = '-'
70 worksheet.cells[index - 1].metadata.slide_helper = '-'
71
58
72 if not isinstance(resources['reveal'], dict):
59 if not isinstance(resources['reveal'], dict):
73 resources['reveal'] = {}
60 resources['reveal'] = {}
@@ -1,17 +1,9 b''
1 """Module containing a preprocessor that converts outputs in the notebook from
1 """Module containing a preprocessor that converts outputs in the notebook from
2 one format to another.
2 one format to another.
3 """
3 """
4 #-----------------------------------------------------------------------------
5 # Copyright (c) 2013, the IPython Development Team.
6 #
7 # Distributed under the terms of the Modified BSD License.
8 #
9 # The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
4
12 #-----------------------------------------------------------------------------
5 # Copyright (c) IPython Development Team.
13 # Imports
6 # Distributed under the terms of the Modified BSD License.
14 #-----------------------------------------------------------------------------
15
7
16 import base64
8 import base64
17 import io
9 import io
@@ -25,15 +17,8 b' from IPython.utils.traitlets import Unicode'
25 from .convertfigures import ConvertFiguresPreprocessor
17 from .convertfigures import ConvertFiguresPreprocessor
26
18
27
19
28 #-----------------------------------------------------------------------------
29 # Constants
30 #-----------------------------------------------------------------------------
31
32 INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
20 INKSCAPE_APP = '/Applications/Inkscape.app/Contents/Resources/bin/inkscape'
33
21
34 #-----------------------------------------------------------------------------
35 # Classes
36 #-----------------------------------------------------------------------------
37
22
38 class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):
23 class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):
39 """
24 """
@@ -41,7 +26,7 b' class SVG2PDFPreprocessor(ConvertFiguresPreprocessor):'
41 """
26 """
42
27
43 def _from_format_default(self):
28 def _from_format_default(self):
44 return 'svg'
29 return 'image/svg+xml'
45 def _to_format_default(self):
30 def _to_format_default(self):
46 return 'application/pdf'
31 return 'application/pdf'
47
32
@@ -1,27 +1,13 b''
1 """
1 """utility functions for preprocessor tests"""
2 Module with utility functions for preprocessor tests
3 """
4
2
5 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
5
13 #-----------------------------------------------------------------------------
6 from IPython.nbformat import v4 as nbformat
14 # Imports
15 #-----------------------------------------------------------------------------
16
17 from IPython.nbformat import current as nbformat
18
7
19 from ...tests.base import TestsBase
8 from ...tests.base import TestsBase
20 from ...exporters.exporter import ResourcesDict
9 from ...exporters.exporter import ResourcesDict
21
10
22 #-----------------------------------------------------------------------------
23 # Class
24 #-----------------------------------------------------------------------------
25
11
26 class PreprocessorTestsBase(TestsBase):
12 class PreprocessorTestsBase(TestsBase):
27 """Contains test functions preprocessor tests"""
13 """Contains test functions preprocessor tests"""
@@ -30,22 +16,21 b' class PreprocessorTestsBase(TestsBase):'
30 def build_notebook(self):
16 def build_notebook(self):
31 """Build a notebook in memory for use with preprocessor tests"""
17 """Build a notebook in memory for use with preprocessor tests"""
32
18
33 outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="a"),
19 outputs = [
34 nbformat.new_output(output_type="text", output_text="b"),
20 nbformat.new_output("stream", name="stdout", text="a"),
35 nbformat.new_output(output_type="stream", stream="stdout", output_text="c"),
21 nbformat.new_output("display_data", data={'text/plain': 'b'}),
36 nbformat.new_output(output_type="stream", stream="stdout", output_text="d"),
22 nbformat.new_output("stream", name="stdout", text="c"),
37 nbformat.new_output(output_type="stream", stream="stderr", output_text="e"),
23 nbformat.new_output("stream", name="stdout", text="d"),
38 nbformat.new_output(output_type="stream", stream="stderr", output_text="f"),
24 nbformat.new_output("stream", name="stderr", text="e"),
39 nbformat.new_output(output_type="png", output_png='Zw==')] # g
25 nbformat.new_output("stream", name="stderr", text="f"),
40 out = nbformat.new_output(output_type="application/pdf")
26 nbformat.new_output("display_data", data={'image/png': 'Zw=='}), # g
41 out['application/pdf'] = 'aA==' # h
27 nbformat.new_output("display_data", data={'application/pdf': 'aA=='}), # h
42 outputs.append(out)
28 ]
43
29
44 cells=[nbformat.new_code_cell(input="$ e $", prompt_number=1,outputs=outputs),
30 cells=[nbformat.new_code_cell(source="$ e $", execution_count=1, outputs=outputs),
45 nbformat.new_text_cell('markdown', source="$ e $")]
31 nbformat.new_markdown_cell(source="$ e $")]
46 worksheets = [nbformat.new_worksheet(cells=cells)]
47
32
48 return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
33 return nbformat.new_notebook(cells=cells)
49
34
50
35
51 def build_resources(self):
36 def build_resources(self):
@@ -1,46 +1,39 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
10 {
5 "execution_count": 1,
11 "cell_type": "code",
6 "metadata": {
12 "collapsed": false,
7 "collapsed": false
13 "input": [
8 },
14 "from IPython.display import clear_output"
9 "outputs": [],
15 ],
10 "source": [
16 "language": "python",
11 "from IPython.display import clear_output"
17 "metadata": {},
12 ]
18 "outputs": [],
13 },
19 "prompt_number": 1
14 {
20 },
15 "cell_type": "code",
16 "execution_count": 2,
17 "metadata": {
18 "collapsed": false
19 },
20 "outputs": [
21 {
21 {
22 "cell_type": "code",
22 "name": "stdout",
23 "collapsed": false,
23 "output_type": "stream",
24 "input": [
24 "text": [
25 "for i in range(10):\n",
25 "9\n"
26 " clear_output()\n",
26 ]
27 " print(i)"
28 ],
29 "language": "python",
30 "metadata": {},
31 "outputs": [
32 {
33 "output_type": "stream",
34 "stream": "stdout",
35 "text": [
36 "9\n"
37 ]
38 }
39 ],
40 "prompt_number": 2
41 }
27 }
42 ],
28 ],
43 "metadata": {}
29 "source": [
30 "for i in range(10):\n",
31 " clear_output()\n",
32 " print(i)"
33 ]
44 }
34 }
45 ]
35 ],
36 "metadata": {},
37 "nbformat": 4,
38 "nbformat_minor": 0
46 } No newline at end of file
39 }
@@ -1,55 +1,48 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
10 {
5 "execution_count": 1,
11 "cell_type": "code",
6 "metadata": {
12 "collapsed": false,
7 "collapsed": false
13 "input": [
8 },
14 "i, j = 1, 1"
9 "outputs": [],
15 ],
10 "source": [
16 "language": "python",
11 "i, j = 1, 1"
17 "metadata": {},
12 ]
18 "outputs": [],
13 },
19 "prompt_number": 1
14 {
20 },
15 "cell_type": "code",
16 "execution_count": 2,
17 "metadata": {
18 "collapsed": false
19 },
20 "outputs": [
21 {
21 {
22 "cell_type": "code",
22 "name": "stdout",
23 "collapsed": false,
23 "output_type": "stream",
24 "input": [
24 "text": [
25 "for m in range(10):\n",
25 "2\n",
26 " i, j = j, i + j\n",
26 "3\n",
27 " print(j)"
27 "5\n",
28 ],
28 "8\n",
29 "language": "python",
29 "13\n",
30 "metadata": {},
30 "21\n",
31 "outputs": [
31 "34\n",
32 {
32 "55\n",
33 "output_type": "stream",
33 "89\n",
34 "stream": "stdout",
34 "144\n"
35 "text": [
35 ]
36 "2\n",
37 "3\n",
38 "5\n",
39 "8\n",
40 "13\n",
41 "21\n",
42 "34\n",
43 "55\n",
44 "89\n",
45 "144\n"
46 ]
47 }
48 ],
49 "prompt_number": 2
50 }
36 }
51 ],
37 ],
52 "metadata": {}
38 "source": [
39 "for m in range(10):\n",
40 " i, j = j, i + j\n",
41 " print(j)"
42 ]
53 }
43 }
54 ]
44 ],
45 "metadata": {},
46 "nbformat": 4,
47 "nbformat_minor": 0
55 } No newline at end of file
48 }
@@ -1,33 +1,26 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": false
8 },
9 "outputs": [
10 {
10 {
11 "cell_type": "code",
11 "name": "stdout",
12 "collapsed": false,
12 "output_type": "stream",
13 "input": [
13 "text": [
14 "print(\"Hello World\")"
14 "Hello World\n"
15 ],
15 ]
16 "language": "python",
17 "metadata": {},
18 "outputs": [
19 {
20 "output_type": "stream",
21 "stream": "stdout",
22 "text": [
23 "Hello World\n"
24 ]
25 }
26 ],
27 "prompt_number": 1
28 }
16 }
29 ],
17 ],
30 "metadata": {}
18 "source": [
19 "print(\"Hello World\")"
20 ]
31 }
21 }
32 ]
22 ],
23 "metadata": {},
24 "nbformat": 4,
25 "nbformat_minor": 0
33 } No newline at end of file
26 }
@@ -1,36 +1,29 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
10 {
5 "execution_count": 1,
11 "cell_type": "code",
6 "metadata": {
12 "collapsed": false,
7 "collapsed": false
13 "input": [
8 },
14 "from IPython.display import Image"
9 "outputs": [],
15 ],
10 "source": [
16 "language": "python",
11 "from IPython.display import Image"
17 "metadata": {},
12 ]
18 "outputs": [],
13 },
19 "prompt_number": 1
14 {
20 },
15 "cell_type": "code",
21 {
16 "execution_count": 2,
22 "cell_type": "code",
17 "metadata": {
23 "collapsed": false,
18 "collapsed": false
24 "input": [
19 },
25 "Image('../input/python.png');"
20 "outputs": [],
26 ],
21 "source": [
27 "language": "python",
22 "Image('../input/python.png');"
28 "metadata": {},
23 ]
29 "outputs": [],
30 "prompt_number": 2
31 }
32 ],
33 "metadata": {}
34 }
24 }
35 ]
25 ],
26 "metadata": {},
27 "nbformat": 4,
28 "nbformat_minor": 0
36 } No newline at end of file
29 }
@@ -1,53 +1,48 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
10 {
5 "execution_count": 1,
11 "cell_type": "code",
6 "metadata": {
12 "collapsed": false,
7 "collapsed": false
13 "input": [
8 },
14 "from IPython.display import SVG"
9 "outputs": [],
15 ],
10 "source": [
16 "language": "python",
11 "from IPython.display import SVG"
17 "metadata": {},
12 ]
18 "outputs": [],
13 },
19 "prompt_number": 1
14 {
20 },
15 "cell_type": "code",
16 "execution_count": 2,
17 "metadata": {
18 "collapsed": false
19 },
20 "outputs": [
21 {
21 {
22 "cell_type": "code",
22 "data": {
23 "collapsed": false,
23 "image/svg+xml": [
24 "input": [
24 "<svg height=\"100\" width=\"100\">\n",
25 "SVG(data='''\n",
25 " <circle cx=\"50\" cy=\"50\" fill=\"red\" r=\"40\" stroke=\"black\" stroke-width=\"2\"/>\n",
26 "<svg height=\"100\" width=\"100\">\n",
26 "</svg>"
27 " <circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n",
27 ],
28 "</svg>''')"
28 "text/plain": [
29 ],
29 "<IPython.core.display.SVG object>"
30 "language": "python",
30 ]
31 },
32 "execution_count": 2,
31 "metadata": {},
33 "metadata": {},
32 "outputs": [
34 "output_type": "execute_result"
33 {
34 "metadata": {},
35 "output_type": "pyout",
36 "prompt_number": 2,
37 "svg": [
38 "<svg height=\"100\" width=\"100\">\n",
39 " <circle cx=\"50\" cy=\"50\" fill=\"red\" r=\"40\" stroke=\"black\" stroke-width=\"2\"/>\n",
40 "</svg>"
41 ],
42 "text": [
43 "<IPython.core.display.SVG at 0x10428e150>"
44 ]
45 }
46 ],
47 "prompt_number": 2
48 }
35 }
49 ],
36 ],
50 "metadata": {}
37 "source": [
38 "SVG(data='''\n",
39 "<svg height=\"100\" width=\"100\">\n",
40 " <circle cx=\"50\" cy=\"50\" r=\"40\" stroke=\"black\" stroke-width=\"2\" fill=\"red\" />\n",
41 "</svg>''')"
42 ]
51 }
43 }
52 ]
44 ],
45 "metadata": {},
46 "nbformat": 4,
47 "nbformat_minor": 0
53 } No newline at end of file
48 }
@@ -1,57 +1,51 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": "",
4 "signature": "sha256:9d47889f0678e9685429071216d0f3354db59bb66489f3225bcadfb6a1a9bbba"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
3 {
10 "cells": [
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": false
8 },
9 "outputs": [
11 {
10 {
12 "cell_type": "code",
11 "ename": "Exception",
13 "collapsed": false,
12 "evalue": "message",
14 "input": [
13 "output_type": "error",
15 "raise Exception(\"message\")"
14 "traceback": [
16 ],
15 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
17 "language": "python",
16 "\u001b[1;31mException\u001b[0m Traceback (most recent call last)",
18 "metadata": {},
17 "\u001b[1;32m<ipython-input-1-335814d14fc1>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"message\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
19 "outputs": [
18 "\u001b[1;31mException\u001b[0m: message"
20 {
19 ]
21 "ename": "Exception",
20 }
22 "evalue": "message",
21 ],
23 "output_type": "pyerr",
22 "source": [
24 "traceback": [
23 "raise Exception(\"message\")"
25 "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
24 ]
26 "\u001b[1;31mException\u001b[0m Traceback (most recent call last)",
25 },
27 "\u001b[1;32m<ipython-input-1-335814d14fc1>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"message\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
26 {
28 "\u001b[1;31mException\u001b[0m: message"
27 "cell_type": "code",
29 ]
28 "execution_count": 2,
30 }
29 "metadata": {
31 ],
30 "collapsed": false
32 "prompt_number": 1
31 },
33 },
32 "outputs": [
34 {
33 {
35 "cell_type": "code",
34 "name": "stdout",
36 "collapsed": false,
35 "output_type": "stream",
37 "input": [
36 "text": [
38 "print('ok')"
37 "ok\n"
39 ],
38 ]
40 "language": "python",
41 "metadata": {},
42 "outputs": [
43 {
44 "output_type": "stream",
45 "stream": "stdout",
46 "text": [
47 "ok\n"
48 ]
49 }
50 ],
51 "prompt_number": 2
52 }
39 }
53 ],
40 ],
54 "metadata": {}
41 "source": [
42 "print('ok')"
43 ]
55 }
44 }
56 ]
45 ],
46 "metadata": {
47 "signature": "sha256:9d47889f0678e9685429071216d0f3354db59bb66489f3225bcadfb6a1a9bbba"
48 },
49 "nbformat": 4,
50 "nbformat_minor": 0
57 } No newline at end of file
51 }
@@ -1,33 +1,26 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": ""
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "code",
5 "execution_count": 1,
6 "metadata": {
7 "collapsed": false
8 },
9 "outputs": [
10 {
10 {
11 "cell_type": "code",
11 "name": "stdout",
12 "collapsed": false,
12 "output_type": "stream",
13 "input": [
13 "text": [
14 "print('\u2603')"
14 "\u2603\n"
15 ],
15 ]
16 "language": "python",
17 "metadata": {},
18 "outputs": [
19 {
20 "output_type": "stream",
21 "stream": "stdout",
22 "text": [
23 "\u2603\n"
24 ]
25 }
26 ],
27 "prompt_number": 1
28 }
16 }
29 ],
17 ],
30 "metadata": {}
18 "source": [
19 "print('\u2603')"
20 ]
31 }
21 }
32 ]
22 ],
23 "metadata": {},
24 "nbformat": 4,
25 "nbformat_minor": 0
33 } No newline at end of file
26 }
@@ -5,19 +5,10 b' Module with tests for the clearoutput preprocessor.'
5 # Copyright (c) IPython Development Team.
5 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
6 # Distributed under the terms of the Modified BSD License.
7
7
8 #-----------------------------------------------------------------------------
9 # Imports
10 #-----------------------------------------------------------------------------
11 from IPython.nbformat import current as nbformat
12
13 from .base import PreprocessorTestsBase
8 from .base import PreprocessorTestsBase
14 from ..clearoutput import ClearOutputPreprocessor
9 from ..clearoutput import ClearOutputPreprocessor
15
10
16
11
17 #-----------------------------------------------------------------------------
18 # Class
19 #-----------------------------------------------------------------------------
20
21 class TestClearOutput(PreprocessorTestsBase):
12 class TestClearOutput(PreprocessorTestsBase):
22 """Contains test functions for clearoutput.py"""
13 """Contains test functions for clearoutput.py"""
23
14
@@ -38,5 +29,5 b' class TestClearOutput(PreprocessorTestsBase):'
38 res = self.build_resources()
29 res = self.build_resources()
39 preprocessor = self.build_preprocessor()
30 preprocessor = self.build_preprocessor()
40 nb, res = preprocessor(nb, res)
31 nb, res = preprocessor(nb, res)
41 assert nb.worksheets[0].cells[0].outputs == []
32 assert nb.cells[0].outputs == []
42 assert nb.worksheets[0].cells[0].prompt_number is None
33 assert nb.cells[0].execution_count is None
@@ -3,7 +3,7 b''
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from IPython.nbformat import current as nbformat
6 from IPython.nbformat import v4 as nbformat
7
7
8 from .base import PreprocessorTestsBase
8 from .base import PreprocessorTestsBase
9 from ..coalescestreams import coalesce_streams
9 from ..coalescestreams import coalesce_streams
@@ -17,44 +17,42 b' class TestCoalesceStreams(PreprocessorTestsBase):'
17 nb = self.build_notebook()
17 nb = self.build_notebook()
18 res = self.build_resources()
18 res = self.build_resources()
19 nb, res = coalesce_streams(nb, res)
19 nb, res = coalesce_streams(nb, res)
20 outputs = nb.worksheets[0].cells[0].outputs
20 outputs = nb.cells[0].outputs
21 self.assertEqual(outputs[0].text, "a")
21 self.assertEqual(outputs[0].text, "a")
22 self.assertEqual(outputs[1].output_type, "text")
22 self.assertEqual(outputs[1].output_type, "display_data")
23 self.assertEqual(outputs[2].text, "cd")
23 self.assertEqual(outputs[2].text, "cd")
24 self.assertEqual(outputs[3].text, "ef")
24 self.assertEqual(outputs[3].text, "ef")
25
25
26 def test_coalesce_sequenced_streams(self):
26 def test_coalesce_sequenced_streams(self):
27 """Can the coalesce streams preprocessor merge a sequence of streams?"""
27 """Can the coalesce streams preprocessor merge a sequence of streams?"""
28 outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="0"),
28 outputs = [nbformat.new_output(output_type="stream", name="stdout", text="0"),
29 nbformat.new_output(output_type="stream", stream="stdout", output_text="1"),
29 nbformat.new_output(output_type="stream", name="stdout", text="1"),
30 nbformat.new_output(output_type="stream", stream="stdout", output_text="2"),
30 nbformat.new_output(output_type="stream", name="stdout", text="2"),
31 nbformat.new_output(output_type="stream", stream="stdout", output_text="3"),
31 nbformat.new_output(output_type="stream", name="stdout", text="3"),
32 nbformat.new_output(output_type="stream", stream="stdout", output_text="4"),
32 nbformat.new_output(output_type="stream", name="stdout", text="4"),
33 nbformat.new_output(output_type="stream", stream="stdout", output_text="5"),
33 nbformat.new_output(output_type="stream", name="stdout", text="5"),
34 nbformat.new_output(output_type="stream", stream="stdout", output_text="6"),
34 nbformat.new_output(output_type="stream", name="stdout", text="6"),
35 nbformat.new_output(output_type="stream", stream="stdout", output_text="7")]
35 nbformat.new_output(output_type="stream", name="stdout", text="7")]
36 cells=[nbformat.new_code_cell(input="# None", prompt_number=1,outputs=outputs)]
36 cells=[nbformat.new_code_cell(source="# None", execution_count=1,outputs=outputs)]
37 worksheets = [nbformat.new_worksheet(cells=cells)]
37
38
38 nb = nbformat.new_notebook(cells=cells)
39 nb = nbformat.new_notebook(name="notebook1", worksheets=worksheets)
40 res = self.build_resources()
39 res = self.build_resources()
41 nb, res = coalesce_streams(nb, res)
40 nb, res = coalesce_streams(nb, res)
42 outputs = nb.worksheets[0].cells[0].outputs
41 outputs = nb.cells[0].outputs
43 self.assertEqual(outputs[0].text, u'01234567')
42 self.assertEqual(outputs[0].text, u'01234567')
44
43
45 def test_coalesce_replace_streams(self):
44 def test_coalesce_replace_streams(self):
46 """Are \\r characters handled?"""
45 """Are \\r characters handled?"""
47 outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="z"),
46 outputs = [nbformat.new_output(output_type="stream", name="stdout", text="z"),
48 nbformat.new_output(output_type="stream", stream="stdout", output_text="\ra"),
47 nbformat.new_output(output_type="stream", name="stdout", text="\ra"),
49 nbformat.new_output(output_type="stream", stream="stdout", output_text="\nz\rb"),
48 nbformat.new_output(output_type="stream", name="stdout", text="\nz\rb"),
50 nbformat.new_output(output_type="stream", stream="stdout", output_text="\nz"),
49 nbformat.new_output(output_type="stream", name="stdout", text="\nz"),
51 nbformat.new_output(output_type="stream", stream="stdout", output_text="\rc\n"),
50 nbformat.new_output(output_type="stream", name="stdout", text="\rc\n"),
52 nbformat.new_output(output_type="stream", stream="stdout", output_text="z\rz\rd")]
51 nbformat.new_output(output_type="stream", name="stdout", text="z\rz\rd")]
53 cells=[nbformat.new_code_cell(input="# None", prompt_number=1,outputs=outputs)]
52 cells=[nbformat.new_code_cell(source="# None", execution_count=1,outputs=outputs)]
54 worksheets = [nbformat.new_worksheet(cells=cells)]
53
55
54 nb = nbformat.new_notebook(cells=cells)
56 nb = nbformat.new_notebook(name="notebook1", worksheets=worksheets)
57 res = self.build_resources()
55 res = self.build_resources()
58 nb, res = coalesce_streams(nb, res)
56 nb, res = coalesce_streams(nb, res)
59 outputs = nb.worksheets[0].cells[0].outputs
57 outputs = nb.cells[0].outputs
60 self.assertEqual(outputs[0].text, u'a\nb\nc\nd')
58 self.assertEqual(outputs[0].text, u'a\nb\nc\nd')
@@ -7,10 +7,11 b' Module with tests for the execute preprocessor.'
7
7
8 import copy
8 import copy
9 import glob
9 import glob
10 import io
10 import os
11 import os
11 import re
12 import re
12
13
13 from IPython.nbformat import current as nbformat
14 from IPython import nbformat
14
15
15 from .base import PreprocessorTestsBase
16 from .base import PreprocessorTestsBase
16 from ..execute import ExecutePreprocessor
17 from ..execute import ExecutePreprocessor
@@ -32,8 +33,9 b' class TestExecute(PreprocessorTestsBase):'
32 del output['metadata']
33 del output['metadata']
33 if 'text' in output:
34 if 'text' in output:
34 output['text'] = re.sub(addr_pat, '<HEXADDR>', output['text'])
35 output['text'] = re.sub(addr_pat, '<HEXADDR>', output['text'])
35 if 'svg' in output:
36 if 'text/plain' in output.get('data', {}):
36 del output['text']
37 output['data']['text/plain'] = \
38 re.sub(addr_pat, '<HEXADDR>', output['data']['text/plain'])
37 if 'traceback' in output:
39 if 'traceback' in output:
38 tb = []
40 tb = []
39 for line in output['traceback']:
41 for line in output['traceback']:
@@ -44,20 +46,20 b' class TestExecute(PreprocessorTestsBase):'
44
46
45
47
46 def assert_notebooks_equal(self, expected, actual):
48 def assert_notebooks_equal(self, expected, actual):
47 expected_cells = expected['worksheets'][0]['cells']
49 expected_cells = expected['cells']
48 actual_cells = actual['worksheets'][0]['cells']
50 actual_cells = actual['cells']
49 assert len(expected_cells) == len(actual_cells)
51 self.assertEqual(len(expected_cells), len(actual_cells))
50
52
51 for expected_cell, actual_cell in zip(expected_cells, actual_cells):
53 for expected_cell, actual_cell in zip(expected_cells, actual_cells):
52 expected_outputs = expected_cell.get('outputs', [])
54 expected_outputs = expected_cell.get('outputs', [])
53 actual_outputs = actual_cell.get('outputs', [])
55 actual_outputs = actual_cell.get('outputs', [])
54 normalized_expected_outputs = list(map(self.normalize_output, expected_outputs))
56 normalized_expected_outputs = list(map(self.normalize_output, expected_outputs))
55 normalized_actual_outputs = list(map(self.normalize_output, actual_outputs))
57 normalized_actual_outputs = list(map(self.normalize_output, actual_outputs))
56 assert normalized_expected_outputs == normalized_actual_outputs
58 self.assertEqual(normalized_expected_outputs, normalized_actual_outputs)
57
59
58 expected_prompt_number = expected_cell.get('prompt_number', None)
60 expected_execution_count = expected_cell.get('execution_count', None)
59 actual_prompt_number = actual_cell.get('prompt_number', None)
61 actual_execution_count = actual_cell.get('execution_count', None)
60 assert expected_prompt_number == actual_prompt_number
62 self.assertEqual(expected_execution_count, actual_execution_count)
61
63
62
64
63 def build_preprocessor(self):
65 def build_preprocessor(self):
@@ -77,14 +79,14 b' class TestExecute(PreprocessorTestsBase):'
77 current_dir = os.path.dirname(__file__)
79 current_dir = os.path.dirname(__file__)
78 input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb'))
80 input_files = glob.glob(os.path.join(current_dir, 'files', '*.ipynb'))
79 for filename in input_files:
81 for filename in input_files:
80 with open(os.path.join(current_dir, 'files', filename)) as f:
82 with io.open(os.path.join(current_dir, 'files', filename)) as f:
81 input_nb = nbformat.read(f, 'ipynb')
83 input_nb = nbformat.read(f, 4)
82 res = self.build_resources()
84 res = self.build_resources()
83 preprocessor = self.build_preprocessor()
85 preprocessor = self.build_preprocessor()
84 cleaned_input_nb = copy.deepcopy(input_nb)
86 cleaned_input_nb = copy.deepcopy(input_nb)
85 for cell in cleaned_input_nb.worksheets[0].cells:
87 for cell in cleaned_input_nb.cells:
86 if 'prompt_number' in cell:
88 if 'execution_count' in cell:
87 del cell['prompt_number']
89 del cell['execution_count']
88 cell['outputs'] = []
90 cell['outputs'] = []
89 output_nb, _ = preprocessor(cleaned_input_nb, res)
91 output_nb, _ = preprocessor(cleaned_input_nb, res)
90 self.assert_notebooks_equal(output_nb, input_nb)
92 self.assert_notebooks_equal(output_nb, input_nb)
@@ -1,43 +1,25 b''
1 """
1 """Tests for the extractoutput preprocessor"""
2 Module with tests for the extractoutput preprocessor
3 """
4
2
5 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
5
17 from .base import PreprocessorTestsBase
6 from .base import PreprocessorTestsBase
18 from ..extractoutput import ExtractOutputPreprocessor
7 from ..extractoutput import ExtractOutputPreprocessor
19
8
20
9
21 #-----------------------------------------------------------------------------
22 # Class
23 #-----------------------------------------------------------------------------
24
25 class TestExtractOutput(PreprocessorTestsBase):
10 class TestExtractOutput(PreprocessorTestsBase):
26 """Contains test functions for extractoutput.py"""
11 """Contains test functions for extractoutput.py"""
27
12
28
29 def build_preprocessor(self):
13 def build_preprocessor(self):
30 """Make an instance of a preprocessor"""
14 """Make an instance of a preprocessor"""
31 preprocessor = ExtractOutputPreprocessor()
15 preprocessor = ExtractOutputPreprocessor()
32 preprocessor.extract_output_types = {'text', 'png', 'application/pdf'}
16 preprocessor.extract_output_types = {'text/plain', 'image/png', 'application/pdf'}
33 preprocessor.enabled = True
17 preprocessor.enabled = True
34 return preprocessor
18 return preprocessor
35
19
36
37 def test_constructor(self):
20 def test_constructor(self):
38 """Can a ExtractOutputPreprocessor be constructed?"""
21 """Can a ExtractOutputPreprocessor be constructed?"""
39 self.build_preprocessor()
22 self.build_preprocessor()
40
41
23
42 def test_output(self):
24 def test_output(self):
43 """Test the output of the ExtractOutputPreprocessor"""
25 """Test the output of the ExtractOutputPreprocessor"""
@@ -45,30 +27,32 b' class TestExtractOutput(PreprocessorTestsBase):'
45 res = self.build_resources()
27 res = self.build_resources()
46 preprocessor = self.build_preprocessor()
28 preprocessor = self.build_preprocessor()
47 nb, res = preprocessor(nb, res)
29 nb, res = preprocessor(nb, res)
48
49 # Check if text was extracted.
30 # Check if text was extracted.
50 output = nb.worksheets[0].cells[0].outputs[1]
31 output = nb.cells[0].outputs[1]
51 assert 'text_filename' in output
32 self.assertIn('filenames', output.metadata)
52 text_filename = output['text_filename']
33 self.assertIn('text/plain', output.metadata.filenames)
34 text_filename = output.metadata.filenames['text/plain']
53
35
54 # Check if png was extracted.
36 # Check if png was extracted.
55 output = nb.worksheets[0].cells[0].outputs[6]
37 output = nb.cells[0].outputs[6]
56 assert 'png_filename' in output
38 self.assertIn('filenames', output.metadata)
57 png_filename = output['png_filename']
39 self.assertIn('image/png', output.metadata.filenames)
40 png_filename = output.metadata.filenames['image/png']
58
41
59 # Check that pdf was extracted
42 # Check that pdf was extracted
60 output = nb.worksheets[0].cells[0].outputs[7]
43 output = nb.cells[0].outputs[7]
61 assert 'application/pdf_filename' in output
44 self.assertIn('filenames', output.metadata)
62 pdf_filename = output['application/pdf_filename']
45 self.assertIn('application/pdf', output.metadata.filenames)
46 pdf_filename = output.metadata.filenames['application/pdf']
63
47
64 # Verify text output
48 # Verify text output
65 assert text_filename in res['outputs']
49 self.assertIn(text_filename, res['outputs'])
66 self.assertEqual(res['outputs'][text_filename], b'b')
50 self.assertEqual(res['outputs'][text_filename], b'b')
67
51
68 # Verify png output
52 # Verify png output
69 assert png_filename in res['outputs']
53 self.assertIn(png_filename, res['outputs'])
70 self.assertEqual(res['outputs'][png_filename], b'g')
54 self.assertEqual(res['outputs'][png_filename], b'g')
71
55
72 # Verify pdf output
56 # Verify pdf output
73 assert pdf_filename in res['outputs']
57 self.assertIn(pdf_filename, res['outputs'])
74 self.assertEqual(res['outputs'][pdf_filename], b'h')
58 self.assertEqual(res['outputs'][pdf_filename], b'h')
@@ -1,27 +1,9 b''
1 """
1 """Tests for the HighlightMagics preprocessor"""
2 Module with tests for the HighlightMagics preprocessor
3 """
4
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
2
17 from .base import PreprocessorTestsBase
3 from .base import PreprocessorTestsBase
18 from ..highlightmagics import HighlightMagicsPreprocessor
4 from ..highlightmagics import HighlightMagicsPreprocessor
19
5
20
6
21 #-----------------------------------------------------------------------------
22 # Class
23 #-----------------------------------------------------------------------------
24
25 class TestHighlightMagics(PreprocessorTestsBase):
7 class TestHighlightMagics(PreprocessorTestsBase):
26 """Contains test functions for highlightmagics.py"""
8 """Contains test functions for highlightmagics.py"""
27
9
@@ -41,7 +23,7 b' class TestHighlightMagics(PreprocessorTestsBase):'
41 nb = self.build_notebook()
23 nb = self.build_notebook()
42 res = self.build_resources()
24 res = self.build_resources()
43 preprocessor = self.build_preprocessor()
25 preprocessor = self.build_preprocessor()
44 nb.worksheets[0].cells[0].input = """%%R -i x,y -o XYcoef
26 nb.cells[0].source = """%%R -i x,y -o XYcoef
45 lm.fit <- lm(y~x)
27 lm.fit <- lm(y~x)
46 par(mfrow=c(2,2))
28 par(mfrow=c(2,2))
47 print(summary(lm.fit))
29 print(summary(lm.fit))
@@ -50,19 +32,19 b' class TestHighlightMagics(PreprocessorTestsBase):'
50
32
51 nb, res = preprocessor(nb, res)
33 nb, res = preprocessor(nb, res)
52
34
53 assert('magics_language' in nb.worksheets[0].cells[0]['metadata'])
35 assert('magics_language' in nb.cells[0]['metadata'])
54
36
55 self.assertEqual(nb.worksheets[0].cells[0]['metadata']['magics_language'], 'r')
37 self.assertEqual(nb.cells[0]['metadata']['magics_language'], 'r')
56
38
57 def test_no_false_positive(self):
39 def test_no_false_positive(self):
58 """Test that HighlightMagicsPreprocessor does not tag false positives"""
40 """Test that HighlightMagicsPreprocessor does not tag false positives"""
59 nb = self.build_notebook()
41 nb = self.build_notebook()
60 res = self.build_resources()
42 res = self.build_resources()
61 preprocessor = self.build_preprocessor()
43 preprocessor = self.build_preprocessor()
62 nb.worksheets[0].cells[0].input = """# this should not be detected
44 nb.cells[0].source = """# this should not be detected
63 print(\"""
45 print(\"""
64 %%R -i x, y
46 %%R -i x, y
65 \""")"""
47 \""")"""
66 nb, res = preprocessor(nb, res)
48 nb, res = preprocessor(nb, res)
67
49
68 assert('magics_language' not in nb.worksheets[0].cells[0]['metadata']) No newline at end of file
50 assert('magics_language' not in nb.cells[0]['metadata']) No newline at end of file
@@ -1,27 +1,12 b''
1 """
1 """Tests for the latex preprocessor"""
2 Module with tests for the latex preprocessor
3 """
4
2
5 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
5
17 from .base import PreprocessorTestsBase
6 from .base import PreprocessorTestsBase
18 from ..latex import LatexPreprocessor
7 from ..latex import LatexPreprocessor
19
8
20
9
21 #-----------------------------------------------------------------------------
22 # Class
23 #-----------------------------------------------------------------------------
24
25 class TestLatex(PreprocessorTestsBase):
10 class TestLatex(PreprocessorTestsBase):
26 """Contains test functions for latex.py"""
11 """Contains test functions for latex.py"""
27
12
@@ -45,7 +30,7 b' class TestLatex(PreprocessorTestsBase):'
45 nb, res = preprocessor(nb, res)
30 nb, res = preprocessor(nb, res)
46
31
47 # Make sure the code cell wasn't modified.
32 # Make sure the code cell wasn't modified.
48 self.assertEqual(nb.worksheets[0].cells[0].input, '$ e $')
33 self.assertEqual(nb.cells[0].source, '$ e $')
49
34
50 # Verify that the markdown cell wasn't processed.
35 # Verify that the markdown cell wasn't processed.
51 self.assertEqual(nb.worksheets[0].cells[1].source, '$ e $')
36 self.assertEqual(nb.cells[1].source, '$ e $')
@@ -3,7 +3,7 b''
3 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
5
5
6 from IPython.nbformat import current as nbformat
6 from IPython.nbformat import v4 as nbformat
7
7
8 from .base import PreprocessorTestsBase
8 from .base import PreprocessorTestsBase
9 from ..revealhelp import RevealHelpPreprocessor
9 from ..revealhelp import RevealHelpPreprocessor
@@ -16,19 +16,18 b' class Testrevealhelp(PreprocessorTestsBase):'
16 """Build a reveal slides notebook in memory for use with tests.
16 """Build a reveal slides notebook in memory for use with tests.
17 Overrides base in PreprocessorTestsBase"""
17 Overrides base in PreprocessorTestsBase"""
18
18
19 outputs = [nbformat.new_output(output_type="stream", stream="stdout", output_text="a")]
19 outputs = [nbformat.new_output(output_type="stream", name="stdout", text="a")]
20
20
21 slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
21 slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
22 subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
22 subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
23
23
24 cells=[nbformat.new_code_cell(input="", prompt_number=1, outputs=outputs),
24 cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs),
25 nbformat.new_text_cell('markdown', source="", metadata=slide_metadata),
25 nbformat.new_markdown_cell(source="", metadata=slide_metadata),
26 nbformat.new_code_cell(input="", prompt_number=2, outputs=outputs),
26 nbformat.new_code_cell(source="", execution_count=2, outputs=outputs),
27 nbformat.new_text_cell('markdown', source="", metadata=slide_metadata),
27 nbformat.new_markdown_cell(source="", metadata=slide_metadata),
28 nbformat.new_text_cell('markdown', source="", metadata=subslide_metadata)]
28 nbformat.new_markdown_cell(source="", metadata=subslide_metadata)]
29 worksheets = [nbformat.new_worksheet(cells=cells)]
30
29
31 return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
30 return nbformat.new_notebook(cells=cells)
32
31
33
32
34 def build_preprocessor(self):
33 def build_preprocessor(self):
@@ -59,7 +58,7 b' class Testrevealhelp(PreprocessorTestsBase):'
59 res = self.build_resources()
58 res = self.build_resources()
60 preprocessor = self.build_preprocessor()
59 preprocessor = self.build_preprocessor()
61 nb, res = preprocessor(nb, res)
60 nb, res = preprocessor(nb, res)
62 cells = nb.worksheets[0].cells
61 cells = nb.cells
63
62
64 # Make sure correct metadata tags are available on every cell.
63 # Make sure correct metadata tags are available on every cell.
65 for cell in cells:
64 for cell in cells:
@@ -1,30 +1,15 b''
1 """
1 """Tests for the svg2pdf preprocessor"""
2 Module with tests for the svg2pdf preprocessor
3 """
4
2
5 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
8 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
12
13 #-----------------------------------------------------------------------------
14 # Imports
15 #-----------------------------------------------------------------------------
16
5
17 from IPython.testing import decorators as dec
6 from IPython.testing import decorators as dec
18 from IPython.nbformat import current as nbformat
7 from IPython.nbformat import v4 as nbformat
19
8
20 from .base import PreprocessorTestsBase
9 from .base import PreprocessorTestsBase
21 from ..svg2pdf import SVG2PDFPreprocessor
10 from ..svg2pdf import SVG2PDFPreprocessor
22
11
23
12
24 #-----------------------------------------------------------------------------
25 # Class
26 #-----------------------------------------------------------------------------
27
28 class Testsvg2pdf(PreprocessorTestsBase):
13 class Testsvg2pdf(PreprocessorTestsBase):
29 """Contains test functions for svg2pdf.py"""
14 """Contains test functions for svg2pdf.py"""
30
15
@@ -54,18 +39,17 b' class Testsvg2pdf(PreprocessorTestsBase):'
54 </svg>"""
39 </svg>"""
55
40
56 def build_notebook(self):
41 def build_notebook(self):
57 """Build a reveal slides notebook in memory for use with tests.
42 """Build a reveal slides notebook in memory for use with tests.
58 Overrides base in PreprocessorTestsBase"""
43 Overrides base in PreprocessorTestsBase"""
59
44
60 outputs = [nbformat.new_output(output_type="svg", output_svg=self.simple_svg)]
45 outputs = [nbformat.new_output(output_type="image/svg+xml", output_svg=self.simple_svg)]
61
46
62 slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
47 slide_metadata = {'slideshow' : {'slide_type': 'slide'}}
63 subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
48 subslide_metadata = {'slideshow' : {'slide_type': 'subslide'}}
64
49
65 cells=[nbformat.new_code_cell(input="", prompt_number=1, outputs=outputs)]
50 cells=[nbformat.new_code_cell(source="", execution_count=1, outputs=outputs)]
66 worksheets = [nbformat.new_worksheet(name="worksheet1", cells=cells)]
67
51
68 return nbformat.new_notebook(name="notebook1", worksheets=worksheets)
52 return nbformat.new_notebook(cells=cells)
69
53
70
54
71 def build_preprocessor(self):
55 def build_preprocessor(self):
@@ -87,4 +71,4 b' class Testsvg2pdf(PreprocessorTestsBase):'
87 res = self.build_resources()
71 res = self.build_resources()
88 preprocessor = self.build_preprocessor()
72 preprocessor = self.build_preprocessor()
89 nb, res = preprocessor(nb, res)
73 nb, res = preprocessor(nb, res)
90 assert 'svg' in nb.worksheets[0].cells[0].outputs[0]
74 self.assertIn('application/pdf', nb.cells[0].outputs[0])
@@ -23,8 +23,8 b''
23
23
24 {% block in_prompt -%}
24 {% block in_prompt -%}
25 <div class="prompt input_prompt">
25 <div class="prompt input_prompt">
26 {%- if cell.prompt_number is defined -%}
26 {%- if cell.execution_count is defined -%}
27 In&nbsp;[{{ cell.prompt_number|replace(None, "&nbsp;") }}]:
27 In&nbsp;[{{ cell.execution_count|replace(None, "&nbsp;") }}]:
28 {%- else -%}
28 {%- else -%}
29 In&nbsp;[&nbsp;]:
29 In&nbsp;[&nbsp;]:
30 {%- endif -%}
30 {%- endif -%}
@@ -46,17 +46,17 b' In&nbsp;[&nbsp;]:'
46 {% block input %}
46 {% block input %}
47 <div class="inner_cell">
47 <div class="inner_cell">
48 <div class="input_area">
48 <div class="input_area">
49 {{ cell.input | highlight_code(metadata=cell.metadata) }}
49 {{ cell.source | highlight_code(metadata=cell.metadata) }}
50 </div>
50 </div>
51 </div>
51 </div>
52 {%- endblock input %}
52 {%- endblock input %}
53
53
54 {% block output %}
54 {% block output %}
55 <div class="output_area">
55 <div class="output_area">
56 {%- if output.output_type == 'pyout' -%}
56 {%- if output.output_type == 'execute_result' -%}
57 <div class="prompt output_prompt">
57 <div class="prompt output_prompt">
58 {%- if cell.prompt_number is defined -%}
58 {%- if cell.execution_count is defined -%}
59 Out[{{ cell.prompt_number|replace(None, "&nbsp;") }}]:
59 Out[{{ cell.execution_count|replace(None, "&nbsp;") }}]:
60 {%- else -%}
60 {%- else -%}
61 Out[&nbsp;]:
61 Out[&nbsp;]:
62 {%- endif -%}
62 {%- endif -%}
@@ -79,28 +79,17 b' In&nbsp;[&nbsp;]:'
79 </div>
79 </div>
80 {%- endblock markdowncell %}
80 {%- endblock markdowncell %}
81
81
82 {% block headingcell scoped %}
83 <div class="cell border-box-sizing text_cell rendered">
84 {{ self.empty_in_prompt() }}
85 <div class="inner_cell">
86 <div class="text_cell_render border-box-sizing rendered_html">
87 {{ ("#" * cell.level + cell.source) | replace('\n', ' ') | markdown2html | strip_files_prefix | add_anchor }}
88 </div>
89 </div>
90 </div>
91 {% endblock headingcell %}
92
93 {% block unknowncell scoped %}
82 {% block unknowncell scoped %}
94 unknown type {{ cell.type }}
83 unknown type {{ cell.type }}
95 {% endblock unknowncell %}
84 {% endblock unknowncell %}
96
85
97 {% block pyout -%}
86 {% block execute_result -%}
98 {%- set extra_class="output_pyout" -%}
87 {%- set extra_class="output_execute_result" -%}
99 {% block data_priority scoped %}
88 {% block data_priority scoped %}
100 {{ super() }}
89 {{ super() }}
101 {% endblock %}
90 {% endblock %}
102 {%- set extra_class="" -%}
91 {%- set extra_class="" -%}
103 {%- endblock pyout %}
92 {%- endblock execute_result %}
104
93
105 {% block stream_stdout -%}
94 {% block stream_stdout -%}
106 <div class="output_subarea output_stream output_stdout output_text">
95 <div class="output_subarea output_stream output_stdout output_text">
@@ -123,28 +112,28 b' unknown type {{ cell.type }}'
123 {%- if output.svg_filename %}
112 {%- if output.svg_filename %}
124 <img src="{{output.svg_filename | posix_path}}"
113 <img src="{{output.svg_filename | posix_path}}"
125 {%- else %}
114 {%- else %}
126 {{ output.svg }}
115 {{ output.data['image/svg+xml'] }}
127 {%- endif %}
116 {%- endif %}
128 </div>
117 </div>
129 {%- endblock data_svg %}
118 {%- endblock data_svg %}
130
119
131 {% block data_html scoped -%}
120 {% block data_html scoped -%}
132 <div class="output_html rendered_html output_subarea {{extra_class}}">
121 <div class="output_html rendered_html output_subarea {{extra_class}}">
133 {{ output.html }}
122 {{ output.data['text/html'] }}
134 </div>
123 </div>
135 {%- endblock data_html %}
124 {%- endblock data_html %}
136
125
137 {% block data_png scoped %}
126 {% block data_png scoped %}
138 <div class="output_png output_subarea {{extra_class}}">
127 <div class="output_png output_subarea {{extra_class}}">
139 {%- if output.png_filename %}
128 {%- if 'image/png' in output.metadata.get('filenames', {}) %}
140 <img src="{{output.png_filename | posix_path}}"
129 <img src="{{output.metadata.filenames['image/png'] | posix_path}}"
141 {%- else %}
130 {%- else %}
142 <img src="data:image/png;base64,{{ output.png }}"
131 <img src="data:image/png;base64,{{ output.data['image/png'] }}"
143 {%- endif %}
132 {%- endif %}
144 {%- if 'metadata' in output and 'width' in output.metadata.get('png', {}) %}
133 {%- if 'width' in output.metadata.get('image/png', {}) %}
145 width={{output.metadata['png']['width']}}
134 width={{output.metadata['png']['width']}}
146 {%- endif %}
135 {%- endif %}
147 {%- if 'metadata' in output and 'height' in output.metadata.get('png', {}) %}
136 {%- if 'height' in output.metadata.get('image/png', {}) %}
148 height={{output.metadata['png']['height']}}
137 height={{output.metadata['png']['height']}}
149 {%- endif %}
138 {%- endif %}
150 >
139 >
@@ -153,16 +142,16 b" height={{output.metadata['png']['height']}}"
153
142
154 {% block data_jpg scoped %}
143 {% block data_jpg scoped %}
155 <div class="output_jpeg output_subarea {{extra_class}}">
144 <div class="output_jpeg output_subarea {{extra_class}}">
156 {%- if output.jpeg_filename %}
145 {%- if 'image/jpeg' in output.metadata.get('filenames', {}) %}
157 <img src="{{output.jpeg_filename | posix_path}}"
146 <img src="{{output.metadata.filenames['image/jpeg'] | posix_path}}"
158 {%- else %}
147 {%- else %}
159 <img src="data:image/jpeg;base64,{{ output.jpeg }}"
148 <img src="data:image/jpeg;base64,{{ output.data['image/jpeg'] }}"
160 {%- endif %}
149 {%- endif %}
161 {%- if 'metadata' in output and 'width' in output.metadata.get('jpeg', {}) %}
150 {%- if 'width' in output.metadata.get('image/jpeg', {}) %}
162 width={{output.metadata['jpeg']['width']}}
151 width={{output.metadata['image/jpeg']['width']}}
163 {%- endif %}
152 {%- endif %}
164 {%- if 'metadata' in output and 'height' in output.metadata.get('jpeg', {}) %}
153 {%- if 'height' in output.metadata.get('image/jpeg', {}) %}
165 height={{output.metadata['jpeg']['height']}}
154 height={{output.metadata['image/jpeg']['height']}}
166 {%- endif %}
155 {%- endif %}
167 >
156 >
168 </div>
157 </div>
@@ -170,17 +159,17 b" height={{output.metadata['jpeg']['height']}}"
170
159
171 {% block data_latex scoped %}
160 {% block data_latex scoped %}
172 <div class="output_latex output_subarea {{extra_class}}">
161 <div class="output_latex output_subarea {{extra_class}}">
173 {{ output.latex }}
162 {{ output.data['text/latex'] }}
174 </div>
163 </div>
175 {%- endblock data_latex %}
164 {%- endblock data_latex %}
176
165
177 {% block pyerr -%}
166 {% block error -%}
178 <div class="output_subarea output_text output_pyerr">
167 <div class="output_subarea output_text output_error">
179 <pre>
168 <pre>
180 {{- super() -}}
169 {{- super() -}}
181 </pre>
170 </pre>
182 </div>
171 </div>
183 {%- endblock pyerr %}
172 {%- endblock error %}
184
173
185 {%- block traceback_line %}
174 {%- block traceback_line %}
186 {{ line | ansi2html }}
175 {{ line | ansi2html }}
@@ -189,7 +178,7 b" height={{output.metadata['jpeg']['height']}}"
189 {%- block data_text scoped %}
178 {%- block data_text scoped %}
190 <div class="output_text output_subarea {{extra_class}}">
179 <div class="output_text output_subarea {{extra_class}}">
191 <pre>
180 <pre>
192 {{- output.text | ansi2html -}}
181 {{- output.data['text/plain'] | ansi2html -}}
193 </pre>
182 </pre>
194 </div>
183 </div>
195 {%- endblock -%}
184 {%- endblock -%}
@@ -197,7 +186,7 b" height={{output.metadata['jpeg']['height']}}"
197 {%- block data_javascript scoped %}
186 {%- block data_javascript scoped %}
198 <div class="output_subarea output_javascript {{extra_class}}">
187 <div class="output_subarea output_javascript {{extra_class}}">
199 <script type="text/javascript">
188 <script type="text/javascript">
200 {{ output.javascript }}
189 {{ output.data['text/javascript'] }}
201 </script>
190 </script>
202 </div>
191 </div>
203 {%- endblock -%}
192 {%- endblock -%}
@@ -135,16 +135,16 b' This template does not define a docclass, the inheriting class must define this.'
135 % Displaying simple data text
135 % Displaying simple data text
136 ((* block data_text *))
136 ((* block data_text *))
137 \begin{verbatim}
137 \begin{verbatim}
138 ((( output.text )))
138 ((( output.data['text/plain'] )))
139 \end{verbatim}
139 \end{verbatim}
140 ((* endblock data_text *))
140 ((* endblock data_text *))
141
141
142 % Display python error text as-is
142 % Display python error text as-is
143 ((* block pyerr *))
143 ((* block error *))
144 \begin{Verbatim}[commandchars=\\\{\}]
144 \begin{Verbatim}[commandchars=\\\{\}]
145 ((( super() )))
145 ((( super() )))
146 \end{Verbatim}
146 \end{Verbatim}
147 ((* endblock pyerr *))
147 ((* endblock error *))
148 ((* block traceback_line *))
148 ((* block traceback_line *))
149 ((( line | indent | strip_ansi | escape_latex )))
149 ((( line | indent | strip_ansi | escape_latex )))
150 ((* endblock traceback_line *))
150 ((* endblock traceback_line *))
@@ -158,21 +158,21 b' This template does not define a docclass, the inheriting class must define this.'
158
158
159 % Display latex
159 % Display latex
160 ((* block data_latex -*))
160 ((* block data_latex -*))
161 ((*- if output.latex.startswith('$'): -*))
161 ((*- if output.data['text/latex'].startswith('$'): -*))
162 ((= Replace $ symbols with more explicit, equation block. =))
162 ((= Replace $ symbols with more explicit, equation block. =))
163 \begin{equation*}\adjustbox{max width=\hsize}{$
163 \begin{equation*}\adjustbox{max width=\hsize}{$
164 ((( output.latex | strip_dollars )))
164 ((( output.data['text/latex'] | strip_dollars )))
165 $}\end{equation*}
165 $}\end{equation*}
166 ((*- else -*))
166 ((*- else -*))
167 ((( output.latex )))
167 ((( output.data['text/latex'] )))
168 ((*- endif *))
168 ((*- endif *))
169 ((* endblock data_latex *))
169 ((* endblock data_latex *))
170
170
171 % Default mechanism for rendering figures
171 % Default mechanism for rendering figures
172 ((*- block data_png -*))((( draw_figure(output.png_filename) )))((*- endblock -*))
172 ((*- block data_png -*))((( draw_figure(output.metadata.filenames['image/png']) )))((*- endblock -*))
173 ((*- block data_jpg -*))((( draw_figure(output.jpeg_filename) )))((*- endblock -*))
173 ((*- block data_jpg -*))((( draw_figure(output.metadata.filenames['image/jpeg']) )))((*- endblock -*))
174 ((*- block data_svg -*))((( draw_figure(output.svg_filename) )))((*- endblock -*))
174 ((*- block data_svg -*))((( draw_figure(output.metadata.filenames['image/svg+xml']) )))((*- endblock -*))
175 ((*- block data_pdf -*))((( draw_figure(output['application/pdf_filename']) )))((*- endblock -*))
175 ((*- block data_pdf -*))((( draw_figure(output.metadata.filenames['application/pdf']) )))((*- endblock -*))
176
176
177 % Draw a figure using the graphicx package.
177 % Draw a figure using the graphicx package.
178 ((* macro draw_figure(filename) -*))
178 ((* macro draw_figure(filename) -*))
@@ -185,33 +185,12 b' This template does not define a docclass, the inheriting class must define this.'
185 ((*- endblock figure -*))
185 ((*- endblock figure -*))
186 ((*- endmacro *))
186 ((*- endmacro *))
187
187
188 % Draw heading cell. Explicitly map different cell levels.
188 % Redirect execute_result to display data priority.
189 ((* block headingcell scoped *))
189 ((* block execute_result scoped *))
190
191 ((* if cell.level == 1 -*))
192 ((* block h1 -*))\section((* endblock h1 -*))
193 ((* elif cell.level == 2 -*))
194 ((* block h2 -*))\subsection((* endblock h2 -*))
195 ((* elif cell.level == 3 -*))
196 ((* block h3 -*))\subsubsection((* endblock h3 -*))
197 ((* elif cell.level == 4 -*))
198 ((* block h4 -*))\paragraph((* endblock h4 -*))
199 ((* elif cell.level == 5 -*))
200 ((* block h5 -*))\subparagraph((* endblock h5 -*))
201 ((* elif cell.level == 6 -*))
202 ((* block h6 -*))\\*\textit((* endblock h6 -*))
203 ((*- endif -*))
204 {((( cell.source | replace('\n', ' ') | citation2latex | strip_files_prefix | prevent_list_blocks | markdown2latex(markup='markdown_strict+tex_math_dollars') )))}
205
206
207 ((* endblock headingcell *))
208
209 % Redirect pyout to display data priority.
210 ((* block pyout scoped *))
211 ((* block data_priority scoped *))
190 ((* block data_priority scoped *))
212 ((( super() )))
191 ((( super() )))
213 ((* endblock *))
192 ((* endblock *))
214 ((* endblock pyout *))
193 ((* endblock execute_result *))
215
194
216 % Render markdown
195 % Render markdown
217 ((* block markdowncell scoped *))
196 ((* block markdowncell scoped *))
@@ -8,38 +8,34 b''
8
8
9
9
10 ((*- block data_priority scoped -*))
10 ((*- block data_priority scoped -*))
11 ((*- for type in output | filter_data_type -*))
11 ((*- for type in output.data | filter_data_type -*))
12 ((*- if type in ['application/pdf']*))
12 ((*- if type == 'application/pdf' -*))
13 ((*- block data_pdf -*))
13 ((*- block data_pdf -*))
14 ((*- endblock -*))
14 ((*- endblock -*))
15 ((*- endif -*))
15 ((*- elif type == 'image/svg+xml' -*))
16 ((*- if type in ['svg']*))
17 ((*- block data_svg -*))
16 ((*- block data_svg -*))
18 ((*- endblock -*))
17 ((*- endblock -*))
19 ((*- endif -*))
18 ((*- elif type == 'image/png' -*))
20 ((*- if type in ['png']*))
21 ((*- block data_png -*))
19 ((*- block data_png -*))
22 ((*- endblock -*))
20 ((*- endblock -*))
23 ((*- endif -*))
21 ((*- elif type == 'text/html' -*))
24 ((*- if type in ['html']*))
25 ((*- block data_html -*))
22 ((*- block data_html -*))
26 ((*- endblock -*))
23 ((*- endblock -*))
27 ((*- endif -*))
24 ((*- elif type == 'image/jpeg' -*))
28 ((*- if type in ['jpeg']*))
29 ((*- block data_jpg -*))
25 ((*- block data_jpg -*))
30 ((*- endblock -*))
26 ((*- endblock -*))
31 ((*- endif -*))
27 ((*- elif type == 'text/plain' -*))
32 ((*- if type in ['text']*))
33 ((*- block data_text -*))
28 ((*- block data_text -*))
34 ((*- endblock -*))
29 ((*- endblock -*))
35 ((*- endif -*))
30 ((*- elif type == 'text/latex' -*))
36 ((*- if type in ['latex']*))
37 ((*- block data_latex -*))
31 ((*- block data_latex -*))
38 ((*- endblock -*))
32 ((*- endblock -*))
39 ((*- endif -*))
33 ((*- elif type == 'application/javascript' -*))
40 ((*- if type in ['javascript']*))
41 ((*- block data_javascript -*))
34 ((*- block data_javascript -*))
42 ((*- endblock -*))
35 ((*- endblock -*))
36 ((*- else -*))
37 ((*- block data_other -*))
38 ((*- endblock -*))
43 ((*- endif -*))
39 ((*- endif -*))
44 ((*- endfor -*))
40 ((*- endfor -*))
45 ((*- endblock data_priority -*))
41 ((*- endblock data_priority -*))
@@ -28,69 +28,64 b' consider calling super even if it is a leave block, we might insert more blocks '
28 ((*- block header -*))
28 ((*- block header -*))
29 ((*- endblock header -*))
29 ((*- endblock header -*))
30 ((*- block body -*))
30 ((*- block body -*))
31 ((*- for worksheet in nb.worksheets -*))
31 ((*- for cell in nb.cells -*))
32 ((*- for cell in worksheet.cells -*))
32 ((*- block any_cell scoped -*))
33 ((*- block any_cell scoped -*))
33 ((*- if cell.cell_type == 'code' -*))
34 ((*- if cell.cell_type in ['code'] -*))
34 ((*- block codecell scoped -*))
35 ((*- block codecell scoped -*))
35 ((*- block input_group -*))
36 ((*- block input_group -*))
36 ((*- block in_prompt -*))((*- endblock in_prompt -*))
37 ((*- block in_prompt -*))((*- endblock in_prompt -*))
37 ((*- block input -*))((*- endblock input -*))
38 ((*- block input -*))((*- endblock input -*))
38 ((*- endblock input_group -*))
39 ((*- endblock input_group -*))
39 ((*- if cell.outputs -*))
40 ((*- if cell.outputs -*))
40 ((*- block output_group -*))
41 ((*- block output_group -*))
41 ((*- block output_prompt -*))((*- endblock output_prompt -*))
42 ((*- block output_prompt -*))((*- endblock output_prompt -*))
42 ((*- block outputs scoped -*))
43 ((*- block outputs scoped -*))
43 ((*- for output in cell.outputs -*))
44 ((*- for output in cell.outputs -*))
44 ((*- block output scoped -*))
45 ((*- block output scoped -*))
45 ((*- if output.output_type == 'execute_result' -*))
46 ((*- if output.output_type in ['pyout'] -*))
46 ((*- block execute_result scoped -*))((*- endblock execute_result -*))
47 ((*- block pyout scoped -*))((*- endblock pyout -*))
47 ((*- elif output.output_type == 'stream' -*))
48 ((*- elif output.output_type in ['stream'] -*))
48 ((*- block stream scoped -*))
49 ((*- block stream scoped -*))
49 ((*- if output.name == 'stdout' -*))
50 ((*- if output.stream in ['stdout'] -*))
50 ((*- block stream_stdout scoped -*))
51 ((*- block stream_stdout scoped -*))
51 ((*- endblock stream_stdout -*))
52 ((*- endblock stream_stdout -*))
52 ((*- elif output.name == 'stderr' -*))
53 ((*- elif output.stream in ['stderr'] -*))
53 ((*- block stream_stderr scoped -*))
54 ((*- block stream_stderr scoped -*))
54 ((*- endblock stream_stderr -*))
55 ((*- endblock stream_stderr -*))
55 ((*- endif -*))
56 ((*- endif -*))
56 ((*- endblock stream -*))
57 ((*- endblock stream -*))
57 ((*- elif output.output_type == 'display_data' -*))
58 ((*- elif output.output_type in ['display_data'] -*))
58 ((*- block display_data scoped -*))
59 ((*- block display_data scoped -*))
59 ((*- block data_priority scoped -*))
60 ((*- block data_priority scoped -*))
60 ((*- endblock data_priority -*))
61 ((*- endblock data_priority -*))
61 ((*- endblock display_data -*))
62 ((*- endblock display_data -*))
62 ((*- elif output.output_type == 'error' -*))
63 ((*- elif output.output_type in ['pyerr'] -*))
63 ((*- block error scoped -*))
64 ((*- block pyerr scoped -*))
64 ((*- for line in output.traceback -*))
65 ((*- for line in output.traceback -*))
65 ((*- block traceback_line scoped -*))((*- endblock traceback_line -*))
66 ((*- block traceback_line scoped -*))((*- endblock traceback_line -*))
66 ((*- endfor -*))
67 ((*- endfor -*))
67 ((*- endblock error -*))
68 ((*- endblock pyerr -*))
68 ((*- endif -*))
69 ((*- endif -*))
69 ((*- endblock output -*))
70 ((*- endblock output -*))
70 ((*- endfor -*))
71 ((*- endfor -*))
71 ((*- endblock outputs -*))
72 ((*- endblock outputs -*))
72 ((*- endblock output_group -*))
73 ((*- endblock output_group -*))
73 ((*- endif -*))
74 ((*- endif -*))
74 ((*- endblock codecell -*))
75 ((*- endblock codecell -*))
75 ((*- elif cell.cell_type in ['markdown'] -*))
76 ((*- elif cell.cell_type in ['markdown'] -*))
76 ((*- block markdowncell scoped-*))
77 ((*- block markdowncell scoped-*))
77 ((*- endblock markdowncell -*))
78 ((*- endblock markdowncell -*))
78 ((*- elif cell.cell_type in ['raw'] -*))
79 ((*- elif cell.cell_type in ['heading'] -*))
79 ((*- block rawcell scoped -*))
80 ((*- block headingcell scoped-*))
80 ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *))
81 ((*- endblock headingcell -*))
81 ((( cell.source )))
82 ((*- elif cell.cell_type in ['raw'] -*))
82 ((* endif *))
83 ((*- block rawcell scoped -*))
83 ((*- endblock rawcell -*))
84 ((* if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) *))
84 ((*- else -*))
85 ((( cell.source )))
85 ((*- block unknowncell scoped-*))
86 ((* endif *))
86 ((*- endblock unknowncell -*))
87 ((*- endblock rawcell -*))
87 ((*- endif -*))
88 ((*- else -*))
88 ((*- endblock any_cell -*))
89 ((*- block unknowncell scoped-*))
90 ((*- endblock unknowncell -*))
91 ((*- endif -*))
92 ((*- endblock any_cell -*))
93 ((*- endfor -*))
94 ((*- endfor -*))
89 ((*- endfor -*))
95 ((*- endblock body -*))
90 ((*- endblock body -*))
96
91
@@ -7,7 +7,7 b''
7 %===============================================================================
7 %===============================================================================
8
8
9 ((* block input scoped *))
9 ((* block input scoped *))
10 ((( add_prompt(cell.input, cell, 'In ') )))
10 ((( add_prompt(cell.source, cell, 'In ') )))
11 ((* endblock input *))
11 ((* endblock input *))
12
12
13
13
@@ -15,15 +15,15 b''
15 % Output
15 % Output
16 %===============================================================================
16 %===============================================================================
17
17
18 ((* block pyout scoped *))
18 ((* block execute_result scoped *))
19 ((*- for type in output | filter_data_type -*))
19 ((*- for type in output.data | filter_data_type -*))
20 ((*- if type in ['text']*))
20 ((*- if type in ['text/plain']*))
21 ((( add_prompt(output.text, cell, 'Out') )))
21 ((( add_prompt(output.data['text/plain'], cell, 'Out') )))
22 ((*- else -*))
22 ((*- else -*))
23 \verb+Out[((( cell.prompt_number )))]:+((( super() )))
23 \verb+Out[((( cell.execution_count )))]:+((( super() )))
24 ((*- endif -*))
24 ((*- endif -*))
25 ((*- endfor -*))
25 ((*- endfor -*))
26 ((* endblock pyout *))
26 ((* endblock execute_result *))
27
27
28
28
29 %==============================================================================
29 %==============================================================================
@@ -33,13 +33,13 b''
33 % Name: draw_prompt
33 % Name: draw_prompt
34 % Purpose: Renders an output/input prompt
34 % Purpose: Renders an output/input prompt
35 ((* macro add_prompt(text, cell, prompt) -*))
35 ((* macro add_prompt(text, cell, prompt) -*))
36 ((*- if cell.prompt_number is defined -*))
36 ((*- if cell.execution_count is defined -*))
37 ((*- set prompt_number = "" ~ (cell.prompt_number | replace(None, " ")) -*))
37 ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*))
38 ((*- else -*))
38 ((*- else -*))
39 ((*- set prompt_number = " " -*))
39 ((*- set execution_count = " " -*))
40 ((*- endif -*))
40 ((*- endif -*))
41 ((*- set indentation = " " * (prompt_number | length + 7) -*))
41 ((*- set indentation = " " * (execution_count | length + 7) -*))
42 \begin{verbatim}
42 \begin{verbatim}
43 (((- text | add_prompts(first=prompt ~ '[' ~ prompt_number ~ ']: ', cont=indentation) -)))
43 (((- text | add_prompts(first=prompt ~ '[' ~ execution_count ~ ']: ', cont=indentation) -)))
44 \end{verbatim}
44 \end{verbatim}
45 ((*- endmacro *))
45 ((*- endmacro *))
@@ -8,6 +8,6 b''
8
8
9 ((* block input scoped *))
9 ((* block input scoped *))
10 \begin{verbatim}
10 \begin{verbatim}
11 ((( cell.input | add_prompts )))
11 ((( cell.source | add_prompts )))
12 \end{verbatim}
12 \end{verbatim}
13 ((* endblock input *))
13 ((* endblock input *))
@@ -20,7 +20,7 b''
20 %===============================================================================
20 %===============================================================================
21
21
22 ((* block input scoped *))
22 ((* block input scoped *))
23 ((( add_prompt(cell.input | highlight_code(strip_verbatim=True), cell, 'In ', 'incolor') )))
23 ((( add_prompt(cell.source | highlight_code(strip_verbatim=True), cell, 'In ', 'incolor') )))
24 ((* endblock input *))
24 ((* endblock input *))
25
25
26
26
@@ -28,15 +28,15 b''
28 % Output
28 % Output
29 %===============================================================================
29 %===============================================================================
30
30
31 ((* block pyout scoped *))
31 ((* block execute_result scoped *))
32 ((*- for type in output | filter_data_type -*))
32 ((*- for type in output.data | filter_data_type -*))
33 ((*- if type in ['text']*))
33 ((*- if type in ['text/plain']*))
34 ((( add_prompt(output.text | escape_latex, cell, 'Out', 'outcolor') )))
34 ((( add_prompt(output.data['text/plain'] | escape_latex, cell, 'Out', 'outcolor') )))
35 ((* else -*))
35 ((* else -*))
36 \texttt{\color{outcolor}Out[{\color{outcolor}((( cell.prompt_number )))}]:}((( super() )))
36 \texttt{\color{outcolor}Out[{\color{outcolor}((( cell.execution_count )))}]:}((( super() )))
37 ((*- endif -*))
37 ((*- endif -*))
38 ((*- endfor -*))
38 ((*- endfor -*))
39 ((* endblock pyout *))
39 ((* endblock execute_result *))
40
40
41
41
42 %==============================================================================
42 %==============================================================================
@@ -46,13 +46,13 b''
46 % Name: draw_prompt
46 % Name: draw_prompt
47 % Purpose: Renders an output/input prompt
47 % Purpose: Renders an output/input prompt
48 ((* macro add_prompt(text, cell, prompt, prompt_color) -*))
48 ((* macro add_prompt(text, cell, prompt, prompt_color) -*))
49 ((*- if cell.prompt_number is defined -*))
49 ((*- if cell.execution_count is defined -*))
50 ((*- set prompt_number = "" ~ (cell.prompt_number | replace(None, " ")) -*))
50 ((*- set execution_count = "" ~ (cell.execution_count | replace(None, " ")) -*))
51 ((*- else -*))
51 ((*- else -*))
52 ((*- set prompt_number = " " -*))
52 ((*- set execution_count = " " -*))
53 ((*- endif -*))
53 ((*- endif -*))
54 ((*- set indention = " " * (prompt_number | length + 7) -*))
54 ((*- set indention = " " * (execution_count | length + 7) -*))
55 \begin{Verbatim}[commandchars=\\\{\}]
55 \begin{Verbatim}[commandchars=\\\{\}]
56 ((( text | add_prompts(first='{\color{' ~ prompt_color ~ '}' ~ prompt ~ '[{\\color{' ~ prompt_color ~ '}' ~ prompt_number ~ '}]:} ', cont=indention) )))
56 ((( text | add_prompts(first='{\color{' ~ prompt_color ~ '}' ~ prompt ~ '[{\\color{' ~ prompt_color ~ '}' ~ execution_count ~ '}]:} ', cont=indention) )))
57 \end{Verbatim}
57 \end{Verbatim}
58 ((*- endmacro *))
58 ((*- endmacro *))
@@ -16,6 +16,6 b''
16
16
17 ((* block input scoped *))
17 ((* block input scoped *))
18 \begin{Verbatim}[commandchars=\\\{\}]
18 \begin{Verbatim}[commandchars=\\\{\}]
19 ((( cell.input | highlight_code(strip_verbatim=True) | add_prompts )))
19 ((( cell.source | highlight_code(strip_verbatim=True) | add_prompts )))
20 \end{Verbatim}
20 \end{Verbatim}
21 ((* endblock input *))
21 ((* endblock input *))
@@ -8,23 +8,23 b''
8 {%- endblock output_prompt %}
8 {%- endblock output_prompt %}
9
9
10 {% block input %}
10 {% block input %}
11 {{ cell.input | indent(4)}}
11 {{ cell.source | indent(4)}}
12 {% endblock input %}
12 {% endblock input %}
13
13
14 {% block pyerr %}
14 {% block error %}
15 {{ super() }}
15 {{ super() }}
16 {% endblock pyerr %}
16 {% endblock error %}
17
17
18 {% block traceback_line %}
18 {% block traceback_line %}
19 {{ line | indent | strip_ansi }}
19 {{ line | indent | strip_ansi }}
20 {% endblock traceback_line %}
20 {% endblock traceback_line %}
21
21
22 {% block pyout %}
22 {% block execute_result %}
23
23
24 {% block data_priority scoped %}
24 {% block data_priority scoped %}
25 {{ super() }}
25 {{ super() }}
26 {% endblock %}
26 {% endblock %}
27 {% endblock pyout %}
27 {% endblock execute_result %}
28
28
29 {% block stream %}
29 {% block stream %}
30 {{ output.text | indent }}
30 {{ output.text | indent }}
@@ -35,34 +35,29 b''
35 {% endblock data_svg %}
35 {% endblock data_svg %}
36
36
37 {% block data_png %}
37 {% block data_png %}
38 ![png]({{ output.png_filename | path2url }})
38 ![png]({{ output.metadata.filenames['image/png'] | path2url }})
39 {% endblock data_png %}
39 {% endblock data_png %}
40
40
41 {% block data_jpg %}
41 {% block data_jpg %}
42 ![jpeg]({{ output.jpeg_filename | path2url }})
42 ![jpeg]({{ output.metadata.filenames['image/jpeg'] | path2url }})
43 {% endblock data_jpg %}
43 {% endblock data_jpg %}
44
44
45 {% block data_latex %}
45 {% block data_latex %}
46 {{ output.latex }}
46 {{ output.data['text/latex'] }}
47 {% endblock data_latex %}
47 {% endblock data_latex %}
48
48
49 {% block data_html scoped %}
49 {% block data_html scoped %}
50 {{ output.html }}
50 {{ output.data['text/html'] }}
51 {% endblock data_html %}
51 {% endblock data_html %}
52
52
53 {% block data_text scoped %}
53 {% block data_text scoped %}
54 {{ output.text | indent }}
54 {{ output.data['text/plain'] | indent }}
55 {% endblock data_text %}
55 {% endblock data_text %}
56
56
57 {% block markdowncell scoped %}
57 {% block markdowncell scoped %}
58 {{ cell.source }}
58 {{ cell.source }}
59 {% endblock markdowncell %}
59 {% endblock markdowncell %}
60
60
61
62 {% block headingcell scoped %}
63 {{ '#' * cell.level }} {{ cell.source | replace('\n', ' ') }}
64 {% endblock headingcell %}
65
66 {% block unknowncell scoped %}
61 {% block unknowncell scoped %}
67 unknown type {{ cell.type }}
62 unknown type {{ cell.type }}
68 {% endblock unknowncell %} No newline at end of file
63 {% endblock unknowncell %}
@@ -5,17 +5,13 b''
5 {% endblock header %}
5 {% endblock header %}
6
6
7 {% block in_prompt %}
7 {% block in_prompt %}
8 # In[{{ cell.prompt_number if cell.prompt_number else ' ' }}]:
8 # In[{{ cell.execution_count if cell.execution_count else ' ' }}]:
9 {% endblock in_prompt %}
9 {% endblock in_prompt %}
10
10
11 {% block input %}
11 {% block input %}
12 {{ cell.input | ipython2python }}
12 {{ cell.source | ipython2python }}
13 {% endblock input %}
13 {% endblock input %}
14
14
15 {% block markdowncell scoped %}
15 {% block markdowncell scoped %}
16 {{ cell.source | comment_lines }}
16 {{ cell.source | comment_lines }}
17 {% endblock markdowncell %}
17 {% endblock markdowncell %}
18
19 {% block headingcell scoped %}
20 {{ '#' * cell.level }}{{ cell.source | replace('\n', ' ') | comment_lines }}
21 {% endblock headingcell %}
@@ -8,28 +8,28 b''
8 {% endblock output_prompt %}
8 {% endblock output_prompt %}
9
9
10 {% block input %}
10 {% block input %}
11 {%- if cell.input.strip() -%}
11 {%- if cell.source.strip() -%}
12 .. code:: python
12 .. code:: python
13
13
14 {{ cell.input | indent}}
14 {{ cell.source | indent}}
15 {%- endif -%}
15 {%- endif -%}
16 {% endblock input %}
16 {% endblock input %}
17
17
18 {% block pyerr %}
18 {% block error %}
19 ::
19 ::
20
20
21 {{ super() }}
21 {{ super() }}
22 {% endblock pyerr %}
22 {% endblock error %}
23
23
24 {% block traceback_line %}
24 {% block traceback_line %}
25 {{ line | indent | strip_ansi }}
25 {{ line | indent | strip_ansi }}
26 {% endblock traceback_line %}
26 {% endblock traceback_line %}
27
27
28 {% block pyout %}
28 {% block execute_result %}
29 {% block data_priority scoped %}
29 {% block data_priority scoped %}
30 {{ super() }}
30 {{ super() }}
31 {% endblock %}
31 {% endblock %}
32 {% endblock pyout %}
32 {% endblock execute_result %}
33
33
34 {% block stream %}
34 {% block stream %}
35 .. parsed-literal::
35 .. parsed-literal::
@@ -38,33 +38,33 b''
38 {% endblock stream %}
38 {% endblock stream %}
39
39
40 {% block data_svg %}
40 {% block data_svg %}
41 .. image:: {{ output.svg_filename|urlencode }}
41 .. image:: {{ output.metadata.filenames['image/svg+xml'] | urlencode }}
42 {% endblock data_svg %}
42 {% endblock data_svg %}
43
43
44 {% block data_png %}
44 {% block data_png %}
45 .. image:: {{ output.png_filename|urlencode }}
45 .. image:: {{ output.metadata.filenames['image/png'] | urlencode }}
46 {% endblock data_png %}
46 {% endblock data_png %}
47
47
48 {% block data_jpg %}
48 {% block data_jpg %}
49 .. image:: {{ output.jpeg_filename|urlencode }}
49 .. image:: {{ output.metadata.filenames['image/jpeg'] | urlencode }}
50 {% endblock data_jpg %}
50 {% endblock data_jpg %}
51
51
52 {% block data_latex %}
52 {% block data_latex %}
53 .. math::
53 .. math::
54
54
55 {{ output.latex | strip_dollars | indent }}
55 {{ output.data['text/latex'] | strip_dollars | indent }}
56 {% endblock data_latex %}
56 {% endblock data_latex %}
57
57
58 {% block data_text scoped %}
58 {% block data_text scoped %}
59 .. parsed-literal::
59 .. parsed-literal::
60
60
61 {{ output.text | indent }}
61 {{ output.data['text/plain'] | indent }}
62 {% endblock data_text %}
62 {% endblock data_text %}
63
63
64 {% block data_html scoped %}
64 {% block data_html scoped %}
65 .. raw:: html
65 .. raw:: html
66
66
67 {{ output.html | indent }}
67 {{ output.data['text/html'] | indent }}
68 {% endblock data_html %}
68 {% endblock data_html %}
69
69
70 {% block markdowncell scoped %}
70 {% block markdowncell scoped %}
@@ -4,38 +4,34 b''
4
4
5
5
6 {%- block data_priority scoped -%}
6 {%- block data_priority scoped -%}
7 {%- for type in output | filter_data_type -%}
7 {%- for type in output.data | filter_data_type -%}
8 {%- if type in ['application/pdf']%}
8 {%- if type == 'application/pdf' -%}
9 {%- block data_pdf -%}
9 {%- block data_pdf -%}
10 {%- endblock -%}
10 {%- endblock -%}
11 {%- endif -%}
11 {%- elif type == 'image/svg+xml' -%}
12 {%- if type in ['svg']%}
13 {%- block data_svg -%}
12 {%- block data_svg -%}
14 {%- endblock -%}
13 {%- endblock -%}
15 {%- endif -%}
14 {%- elif type == 'image/png' -%}
16 {%- if type in ['png']%}
17 {%- block data_png -%}
15 {%- block data_png -%}
18 {%- endblock -%}
16 {%- endblock -%}
19 {%- endif -%}
17 {%- elif type == 'text/html' -%}
20 {%- if type in ['html']%}
21 {%- block data_html -%}
18 {%- block data_html -%}
22 {%- endblock -%}
19 {%- endblock -%}
23 {%- endif -%}
20 {%- elif type == 'image/jpeg' -%}
24 {%- if type in ['jpeg']%}
25 {%- block data_jpg -%}
21 {%- block data_jpg -%}
26 {%- endblock -%}
22 {%- endblock -%}
27 {%- endif -%}
23 {%- elif type == 'text/plain' -%}
28 {%- if type in ['text']%}
29 {%- block data_text -%}
24 {%- block data_text -%}
30 {%- endblock -%}
25 {%- endblock -%}
31 {%- endif -%}
26 {%- elif type == 'text/latex' -%}
32 {%- if type in ['latex']%}
33 {%- block data_latex -%}
27 {%- block data_latex -%}
34 {%- endblock -%}
28 {%- endblock -%}
35 {%- endif -%}
29 {%- elif type == 'application/javascript' -%}
36 {%- if type in ['javascript']%}
37 {%- block data_javascript -%}
30 {%- block data_javascript -%}
38 {%- endblock -%}
31 {%- endblock -%}
32 {%- else -%}
33 {%- block data_other -%}
34 {%- endblock -%}
39 {%- endif -%}
35 {%- endif -%}
40 {%- endfor -%}
36 {%- endfor -%}
41 {%- endblock data_priority -%}
37 {%- endblock data_priority -%}
@@ -24,69 +24,64 b' consider calling super even if it is a leave block, we might insert more blocks '
24 {%- block header -%}
24 {%- block header -%}
25 {%- endblock header -%}
25 {%- endblock header -%}
26 {%- block body -%}
26 {%- block body -%}
27 {%- for worksheet in nb.worksheets -%}
27 {%- for cell in nb.cells -%}
28 {%- for cell in worksheet.cells -%}
28 {%- block any_cell scoped -%}
29 {%- block any_cell scoped -%}
29 {%- if cell.cell_type == 'code' -%}
30 {%- if cell.cell_type in ['code'] -%}
30 {%- block codecell scoped -%}
31 {%- block codecell scoped -%}
31 {%- block input_group -%}
32 {%- block input_group -%}
32 {%- block in_prompt -%}{%- endblock in_prompt -%}
33 {%- block in_prompt -%}{%- endblock in_prompt -%}
33 {%- block input -%}{%- endblock input -%}
34 {%- block input -%}{%- endblock input -%}
34 {%- endblock input_group -%}
35 {%- endblock input_group -%}
35 {%- if cell.outputs -%}
36 {%- if cell.outputs -%}
36 {%- block output_group -%}
37 {%- block output_group -%}
37 {%- block output_prompt -%}{%- endblock output_prompt -%}
38 {%- block output_prompt -%}{%- endblock output_prompt -%}
38 {%- block outputs scoped -%}
39 {%- block outputs scoped -%}
39 {%- for output in cell.outputs -%}
40 {%- for output in cell.outputs -%}
40 {%- block output scoped -%}
41 {%- block output scoped -%}
41 {%- if output.output_type == 'execute_result' -%}
42 {%- if output.output_type in ['pyout'] -%}
42 {%- block execute_result scoped -%}{%- endblock execute_result -%}
43 {%- block pyout scoped -%}{%- endblock pyout -%}
43 {%- elif output.output_type == 'stream' -%}
44 {%- elif output.output_type in ['stream'] -%}
44 {%- block stream scoped -%}
45 {%- block stream scoped -%}
45 {%- if output.name == 'stdout' -%}
46 {%- if output.stream in ['stdout'] -%}
46 {%- block stream_stdout scoped -%}
47 {%- block stream_stdout scoped -%}
47 {%- endblock stream_stdout -%}
48 {%- endblock stream_stdout -%}
48 {%- elif output.name == 'stderr' -%}
49 {%- elif output.stream in ['stderr'] -%}
49 {%- block stream_stderr scoped -%}
50 {%- block stream_stderr scoped -%}
50 {%- endblock stream_stderr -%}
51 {%- endblock stream_stderr -%}
51 {%- endif -%}
52 {%- endif -%}
52 {%- endblock stream -%}
53 {%- endblock stream -%}
53 {%- elif output.output_type == 'display_data' -%}
54 {%- elif output.output_type in ['display_data'] -%}
54 {%- block display_data scoped -%}
55 {%- block display_data scoped -%}
55 {%- block data_priority scoped -%}
56 {%- block data_priority scoped -%}
56 {%- endblock data_priority -%}
57 {%- endblock data_priority -%}
57 {%- endblock display_data -%}
58 {%- endblock display_data -%}
58 {%- elif output.output_type == 'error' -%}
59 {%- elif output.output_type in ['pyerr'] -%}
59 {%- block error scoped -%}
60 {%- block pyerr scoped -%}
60 {%- for line in output.traceback -%}
61 {%- for line in output.traceback -%}
61 {%- block traceback_line scoped -%}{%- endblock traceback_line -%}
62 {%- block traceback_line scoped -%}{%- endblock traceback_line -%}
62 {%- endfor -%}
63 {%- endfor -%}
63 {%- endblock error -%}
64 {%- endblock pyerr -%}
64 {%- endif -%}
65 {%- endif -%}
65 {%- endblock output -%}
66 {%- endblock output -%}
66 {%- endfor -%}
67 {%- endfor -%}
67 {%- endblock outputs -%}
68 {%- endblock outputs -%}
68 {%- endblock output_group -%}
69 {%- endblock output_group -%}
69 {%- endif -%}
70 {%- endif -%}
70 {%- endblock codecell -%}
71 {%- endblock codecell -%}
71 {%- elif cell.cell_type in ['markdown'] -%}
72 {%- elif cell.cell_type in ['markdown'] -%}
72 {%- block markdowncell scoped-%}
73 {%- block markdowncell scoped-%}
73 {%- endblock markdowncell -%}
74 {%- endblock markdowncell -%}
74 {%- elif cell.cell_type in ['raw'] -%}
75 {%- elif cell.cell_type in ['heading'] -%}
75 {%- block rawcell scoped -%}
76 {%- block headingcell scoped-%}
76 {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %}
77 {%- endblock headingcell -%}
77 {{ cell.source }}
78 {%- elif cell.cell_type in ['raw'] -%}
78 {% endif %}
79 {%- block rawcell scoped -%}
79 {%- endblock rawcell -%}
80 {% if cell.metadata.get('raw_mimetype', '').lower() in resources.get('raw_mimetypes', ['']) %}
80 {%- else -%}
81 {{ cell.source }}
81 {%- block unknowncell scoped-%}
82 {% endif %}
82 {%- endblock unknowncell -%}
83 {%- endblock rawcell -%}
83 {%- endif -%}
84 {%- else -%}
84 {%- endblock any_cell -%}
85 {%- block unknowncell scoped-%}
86 {%- endblock unknowncell -%}
87 {%- endif -%}
88 {%- endblock any_cell -%}
89 {%- endfor -%}
90 {%- endfor -%}
85 {%- endfor -%}
91 {%- endblock body -%}
86 {%- endblock body -%}
92
87
@@ -1,17 +1,7 b''
1 """
1 """Base test class for nbconvert"""
2 Contains base test class for nbconvert
2
3 """
3 # Copyright (c) IPython Development Team.
4 #-----------------------------------------------------------------------------
4 # Distributed under the terms of the Modified BSD License.
5 #Copyright (c) 2013, the IPython Development Team.
6 #
7 #Distributed under the terms of the Modified BSD License.
8 #
9 #The full license is in the file COPYING.txt, distributed with this software.
10 #-----------------------------------------------------------------------------
11
12 #-----------------------------------------------------------------------------
13 # Imports
14 #-----------------------------------------------------------------------------
15
5
16 import io
6 import io
17 import os
7 import os
@@ -20,7 +10,7 b' import shutil'
20 import unittest
10 import unittest
21
11
22 import IPython
12 import IPython
23 from IPython.nbformat import current
13 from IPython.nbformat import v4, write
24 from IPython.utils.tempdir import TemporaryWorkingDirectory
14 from IPython.utils.tempdir import TemporaryWorkingDirectory
25 from IPython.utils.path import get_ipython_package_dir
15 from IPython.utils.path import get_ipython_package_dir
26 from IPython.utils.process import get_output_error_code
16 from IPython.utils.process import get_output_error_code
@@ -29,10 +19,6 b' from IPython.testing.tools import get_ipython_cmd'
29 # a trailing space allows for simpler concatenation with the other arguments
19 # a trailing space allows for simpler concatenation with the other arguments
30 ipy_cmd = get_ipython_cmd(as_string=True) + " "
20 ipy_cmd = get_ipython_cmd(as_string=True) + " "
31
21
32 #-----------------------------------------------------------------------------
33 # Classes and functions
34 #-----------------------------------------------------------------------------
35
36
22
37 class TestsBase(unittest.TestCase):
23 class TestsBase(unittest.TestCase):
38 """Base tests class. Contains useful fuzzy comparison and nbconvert
24 """Base tests class. Contains useful fuzzy comparison and nbconvert
@@ -115,11 +101,9 b' class TestsBase(unittest.TestCase):'
115 return temp_dir
101 return temp_dir
116
102
117 def create_empty_notebook(self, path):
103 def create_empty_notebook(self, path):
118 nb = current.new_notebook()
104 nb = v4.new_notebook()
119 nb.worksheets.append(current.new_worksheet())
120 with io.open(path, 'w', encoding='utf-8') as f:
105 with io.open(path, 'w', encoding='utf-8') as f:
121 current.write(nb, f, 'json')
106 write(nb, f, 4)
122
123
107
124 def copy_files_to(self, copy_filenames, dest='.'):
108 def copy_files_to(self, copy_filenames, dest='.'):
125 "Copy test files into the destination directory"
109 "Copy test files into the destination directory"
@@ -1,149 +1,189 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": "notebook1"
4 },
5 "nbformat": 3,
6 "nbformat_minor": 0,
7 "worksheets": [
8 {
3 {
9 "cells": [
4 "cell_type": "markdown",
10 {
5 "metadata": {},
11 "cell_type": "heading",
6 "source": [
12 "level": 1,
7 "# A simple SymPy example"
13 "metadata": {},
8 ]
14 "source": [
9 },
15 "A simple SymPy example"
10 {
16 ]
11 "cell_type": "markdown",
17 },
12 "metadata": {},
18 {
13 "source": [
19 "cell_type": "markdown",
14 "First we import SymPy and initialize printing:"
20 "metadata": {},
15 ]
21 "source": [
16 },
22 "First we import SymPy and initialize printing:"
17 {
23 ]
18 "cell_type": "code",
24 },
19 "execution_count": 2,
25 {
20 "metadata": {
26 "cell_type": "code",
21 "collapsed": false
27 "collapsed": false,
22 },
28 "input": [
23 "outputs": [],
29 "from sympy import init_printing\n",
24 "source": [
30 "from sympy import *\n",
25 "from sympy import init_printing\n",
31 " init_printing()"
26 "from sympy import *\n",
32 ],
27 " init_printing()"
33 "language": "python",
28 ]
34 "metadata": {},
29 },
35 "outputs": [],
30 {
36 "prompt_number": 2
31 "cell_type": "markdown",
37 },
32 "metadata": {},
38 {
33 "source": [
39 "cell_type": "markdown",
34 "Create a few symbols:"
40 "metadata": {},
35 ]
41 "source": [
36 },
42 "Create a few symbols:"
37 {
43 ]
38 "cell_type": "code",
44 },
39 "execution_count": 4,
45 {
40 "metadata": {
46 "cell_type": "code",
41 "collapsed": false
47 "collapsed": false,
42 },
48 "input": [
43 "outputs": [],
49 "x,y,z = symbols('x y z')"
44 "source": [
50 ],
45 "x,y,z = symbols('x y z')"
51 "language": "python",
46 ]
52 "metadata": {},
47 },
53 "outputs": [],
48 {
54 "prompt_number": 4
49 "cell_type": "markdown",
55 },
50 "metadata": {},
56 {
51 "source": [
57 "cell_type": "markdown",
52 "Here is a basic expression:"
58 "metadata": {},
53 ]
59 "source": [
54 },
60 "Here is a basic expression:"
55 {
61 ]
56 "cell_type": "code",
62 },
57 "execution_count": 6,
63 {
58 "metadata": {
64 "cell_type": "code",
59 "collapsed": false
65 "collapsed": false,
60 },
66 "input": [
61 "outputs": [
67 "e = x**2 + 2.0*y + sin(z); e"
68 ],
69 "language": "python",
70 "metadata": {},
71 "outputs": [
72 {
73 "latex": [
74 "$$x^{2} + 2.0 y + \\sin{\\left (z \\right )}$$"
75 ],
76 "metadata": {},
77 "output_type": "pyout",
78 "png": "iVBORw0KGgoAAAANSUhEUgAAAKMAAAAZBAMAAACvE4OgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\nme8Q6PJIAAACz0lEQVRIDa1UTWjUQBT+ZpvdzW7TGlrxItjYSg/C6vbiDwjmoCgUpHioPYhdqig9\nFJYiPYmW4klB14NgFGnw4EHpj7UgUtTFXhSEBgVBxIOFggWVrrUqiMY3mZkkLNIK7oN575vvvfky\n8yYJIGzgkSlRrULKrivVSkvq6LbxtcaSjV3aSo0lgWyl5pK69V+SRlEsPxNTGYhhDrV3M2Ue2etc\nEDmuMmM+IjolrCuHXNoLoQDNSAXdzbjsfFVKTY1vCgFXFIxenG4cFSSzRewAPnN0FugXjPDr45MQ\nJwoKtitgXL9zT+CsJeIHYG+Z4H1gwhRU4G/FcAQbbYU3KdDo+0sCK8lRU0guA72uKqMYk9RehHxP\niDIu0NS2v90KGShJYi7T7tgvkrQ2vIT2XtRISWNra6lzGc8/PW3ji4PL7Vmge095YIX0iB71NCaZ\n5N3XyM0VCuNIyFNIyY3AMG/KDUvjn90DGmwq9wpIl5AyU5WsTYy0aJf6JFGB5An3Der5jExKHjNR\n4JKPge/EXqDBoOXpkxkmkJHFfAFRVhDIveWA0S57N2Me6yw+DSX1n1uCq3sIfCF2IcjNkjeWyKli\nginHubboOB4vSNAjyaiXE26ygrkyTfod55Lj3CTE+n2P73ImJpnk6wJJKjYJSwt3OQbNJu4icM5s\nKGGbzMuD70N6JSbJD44x7pLDyJrbkfiLpOEhYVMJSVEj83x5YFLyNrAzJsmvJ+uhLrieXvcJDshy\nHtQuD54c2IWWEnSXfUTDZJJfAjcpOW5imp9aHvw4ZZ4NDV4FGjw0tzadKgbFwinJUd//AT0P1tdW\nBtuRU39oKdk9ONQ163fM+nvu/s4D/FX30otdQIZGlSnJKpq6KUxKVqV1WxGHFIhishjhEO1Gi3r4\nkZCMg+hH1henV8EjmFoly1PTMs/Uadaox+FceY2STpmvt9co/Pe0Jvt1GvgDK/Osw/4jQ4wAAAAA\nSUVORK5CYII=\n",
79 "prompt_number": 6,
80 "text": [
81 " 2 \n",
82 "x + 2.0\u22c5y + sin(z)"
83 ]
84 }
85 ],
86 "prompt_number": 6
87 },
88 {
62 {
89 "cell_type": "code",
63 "data": {
90 "collapsed": false,
64 "image/png": [
91 "input": [
65 "iVBORw0KGgoAAAANSUhEUgAAAKMAAAAZBAMAAACvE4OgAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n",
92 "diff(e, x)"
66 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n",
93 ],
67 "me8Q6PJIAAACz0lEQVRIDa1UTWjUQBT+ZpvdzW7TGlrxItjYSg/C6vbiDwjmoCgUpHioPYhdqig9\n",
94 "language": "python",
68 "FJYiPYmW4klB14NgFGnw4EHpj7UgUtTFXhSEBgVBxIOFggWVrrUqiMY3mZkkLNIK7oN575vvvfky\n",
69 "8yYJIGzgkSlRrULKrivVSkvq6LbxtcaSjV3aSo0lgWyl5pK69V+SRlEsPxNTGYhhDrV3M2Ue2etc\n",
70 "EDmuMmM+IjolrCuHXNoLoQDNSAXdzbjsfFVKTY1vCgFXFIxenG4cFSSzRewAPnN0FugXjPDr45MQ\n",
71 "JwoKtitgXL9zT+CsJeIHYG+Z4H1gwhRU4G/FcAQbbYU3KdDo+0sCK8lRU0guA72uKqMYk9RehHxP\n",
72 "iDIu0NS2v90KGShJYi7T7tgvkrQ2vIT2XtRISWNra6lzGc8/PW3ji4PL7Vmge095YIX0iB71NCaZ\n",
73 "5N3XyM0VCuNIyFNIyY3AMG/KDUvjn90DGmwq9wpIl5AyU5WsTYy0aJf6JFGB5An3Der5jExKHjNR\n",
74 "4JKPge/EXqDBoOXpkxkmkJHFfAFRVhDIveWA0S57N2Me6yw+DSX1n1uCq3sIfCF2IcjNkjeWyKli\n",
75 "ginHubboOB4vSNAjyaiXE26ygrkyTfod55Lj3CTE+n2P73ImJpnk6wJJKjYJSwt3OQbNJu4icM5s\n",
76 "KGGbzMuD70N6JSbJD44x7pLDyJrbkfiLpOEhYVMJSVEj83x5YFLyNrAzJsmvJ+uhLrieXvcJDshy\n",
77 "HtQuD54c2IWWEnSXfUTDZJJfAjcpOW5imp9aHvw4ZZ4NDV4FGjw0tzadKgbFwinJUd//AT0P1tdW\n",
78 "BtuRU39oKdk9ONQ163fM+nvu/s4D/FX30otdQIZGlSnJKpq6KUxKVqV1WxGHFIhishjhEO1Gi3r4\n",
79 "kZCMg+hH1henV8EjmFoly1PTMs/Uadaox+FceY2STpmvt9co/Pe0Jvt1GvgDK/Osw/4jQ4wAAAAA\n",
80 "SUVORK5CYII=\n"
81 ],
82 "text/latex": [
83 "$$x^{2} + 2.0 y + \\sin{\\left (z \\right )}$$"
84 ],
85 "text/plain": [
86 " 2 \n",
87 "x + 2.0\u22c5y + sin(z)"
88 ]
89 },
90 "execution_count": 6,
95 "metadata": {},
91 "metadata": {},
96 "outputs": [
92 "output_type": "execute_result"
97 {
93 }
98 "latex": [
94 ],
99 "$$2 x$$"
95 "source": [
100 ],
96 "e = x**2 + 2.0*y + sin(z); e"
101 "metadata": {},
97 ]
102 "output_type": "pyout",
98 },
103 "png": "iVBORw0KGgoAAAANSUhEUgAAABQAAAAOBAMAAADd6iHDAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpm7MhCriUTv3c12\nVGZoascqAAAAgElEQVQIHWNgVDJ2YICAMAb2H1BmKgPDTChzFgNDvgOEvT8AzgQKrA9gPZPYUwNk\ncXxnCGd4dWA1kMllwFDKUB9wEchUZmAIYNgMZDDwJIDIPyDiEgOjAAPLFwZWBhYFBh6BqzwfGI4y\nSJUXZXH8Zf7A+IBh////v1hzjh5/xwAAW80hUDE8HYkAAAAASUVORK5CYII=\n",
99 {
104 "prompt_number": 7,
100 "cell_type": "code",
105 "text": [
101 "execution_count": 7,
106 "2\u22c5x"
102 "metadata": {
107 ]
103 "collapsed": false
108 }
104 },
109 ],
105 "outputs": [
110 "prompt_number": 7
111 },
112 {
106 {
113 "cell_type": "code",
107 "data": {
114 "collapsed": false,
108 "image/png": [
115 "input": [
109 "iVBORw0KGgoAAAANSUhEUgAAABQAAAAOBAMAAADd6iHDAAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n",
116 "integrate(e, z)"
110 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAIpm7MhCriUTv3c12\n",
117 ],
111 "VGZoascqAAAAgElEQVQIHWNgVDJ2YICAMAb2H1BmKgPDTChzFgNDvgOEvT8AzgQKrA9gPZPYUwNk\n",
118 "language": "python",
112 "cXxnCGd4dWA1kMllwFDKUB9wEchUZmAIYNgMZDDwJIDIPyDiEgOjAAPLFwZWBhYFBh6BqzwfGI4y\n",
113 "SJUXZXH8Zf7A+IBh////v1hzjh5/xwAAW80hUDE8HYkAAAAASUVORK5CYII=\n"
114 ],
115 "text/latex": [
116 "$$2 x$$"
117 ],
118 "text/plain": [
119 "2\u22c5x"
120 ]
121 },
122 "execution_count": 7,
119 "metadata": {},
123 "metadata": {},
120 "outputs": [
124 "output_type": "execute_result"
121 {
125 }
122 "latex": [
126 ],
123 "$$x^{2} z + 2.0 y z - \\cos{\\left (z \\right )}$$"
127 "source": [
124 ],
128 "diff(e, x)"
125 "metadata": {},
129 ]
126 "output_type": "pyout",
130 },
127 "png": "iVBORw0KGgoAAAANSUhEUgAAALsAAAAZBAMAAACbakK8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\nme8Q6PJIAAADAklEQVRIDbVVS2gTURQ90/wmk0k6tCJCsR1SKShIsxE3CgNWBKUxq9qFmqFqShfF\nUKQrkaDiF0pcCKYgBBcuBLV+wIWKARe6kQ4UhNKKWdiF4KIptmA/xPvmzZuMxdYUzIPcd+655568\nvLlJAL6G32oOasQWNHz5Rvg6nrKh/mygfSzlX2ygPaBUGmov6//NXs1yq4sex2EPrsHemTd2snNg\ntkb+Cx1zBL6SqwxZLvQAKYHzKZaPY4fh4TeHd0S5Nox9OClItm/jiU9DrEwwVEawpiVis9VkimqX\nAOr4o2cCs/0BT2I5+FYJRhJbePQxgzcD7QLEqtV5gdnu2Icr3L45gcCyt74Z7neL4SLQ0nm4S+dM\nYCz1gSPHnhKZDWyHhcCCNKwjqaF/TkwGl0L6nClie/wc1D1xdoNsSLhT0IJkhi7Lzr22xb8keE/N\nPm0Sc9yEuhRUyuiG9HzvFNeImCyq39SriOhtQI7IV/TiTqE8glqwohjE0NJwiANxOZTdZoxtfzSa\nx2tI8DtHcKQoQFmV6f1XT2swibxFL+6k5EgenhBCqKLTPX3ULnaYdDlaTMcCSd8zuXTvBq2bJUJr\nlE4WgSV5ZRdBzLFgO6nzhJp1ltvrlB2HCoWxQuG+jTvt2GxBWUZaU2mMApZNuSHA3vJpCliRhqqs\nZtvbTrb9ZIk+i70Ut1OcnpgeKskTCFUwjaYy8Jhr3eiefq0HIfa7yC6HOwVyULRuNDn21JngbcL+\nE8A+MNnSxb+w59+Cj2tELJBbjEZr8SGwn0j2aLkTPdp08R2OcKV6fXB3ikPH3n8tM5WTfrETtZcw\ng3QWH0dH7nKNiMkszqo/EDafaHhJ5Bm6ee4UtdAabxnMcmUUl0SnYx+uVqs5XAGN9QGgdeCrASv0\n3TmCsJcOdhnozexD38goK9HXynEKr1OKDs9guhQD039kGySyIQpJAdbvJ9YTlPvyUl3/aLUf34G/\nuGxIyXpE37DoLbAHwJaU53t9MRCfrU8o/k4iRn36Lar8Wd5wAfgN4R6xelyy/ssAAAAASUVORK5C\nYII=\n",
131 {
128 "prompt_number": 8,
132 "cell_type": "code",
129 "text": [
133 "execution_count": 8,
130 " 2 \n",
134 "metadata": {
131 "x \u22c5z + 2.0\u22c5y\u22c5z - cos(z)"
135 "collapsed": false
132 ]
136 },
133 }
137 "outputs": [
134 ],
135 "prompt_number": 8
136 },
137 {
138 {
138 "cell_type": "code",
139 "data": {
139 "collapsed": false,
140 "image/png": [
140 "input": [],
141 "iVBORw0KGgoAAAANSUhEUgAAALsAAAAZBAMAAACbakK8AAAAMFBMVEX///8AAAAAAAAAAAAAAAAA\n",
141 "language": "python",
142 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAv3aB7AAAAD3RSTlMAEHarIkSJZt3NVLsy\n",
143 "me8Q6PJIAAADAklEQVRIDbVVS2gTURQ90/wmk0k6tCJCsR1SKShIsxE3CgNWBKUxq9qFmqFqShfF\n",
144 "UKQrkaDiF0pcCKYgBBcuBLV+wIWKARe6kQ4UhNKKWdiF4KIptmA/xPvmzZuMxdYUzIPcd+655568\n",
145 "vLlJAL6G32oOasQWNHz5Rvg6nrKh/mygfSzlX2ygPaBUGmov6//NXs1yq4sex2EPrsHemTd2snNg\n",
146 "tkb+Cx1zBL6SqwxZLvQAKYHzKZaPY4fh4TeHd0S5Nox9OClItm/jiU9DrEwwVEawpiVis9VkimqX\n",
147 "AOr4o2cCs/0BT2I5+FYJRhJbePQxgzcD7QLEqtV5gdnu2Icr3L45gcCyt74Z7neL4SLQ0nm4S+dM\n",
148 "YCz1gSPHnhKZDWyHhcCCNKwjqaF/TkwGl0L6nClie/wc1D1xdoNsSLhT0IJkhi7Lzr22xb8keE/N\n",
149 "Pm0Sc9yEuhRUyuiG9HzvFNeImCyq39SriOhtQI7IV/TiTqE8glqwohjE0NJwiANxOZTdZoxtfzSa\n",
150 "x2tI8DtHcKQoQFmV6f1XT2swibxFL+6k5EgenhBCqKLTPX3ULnaYdDlaTMcCSd8zuXTvBq2bJUJr\n",
151 "lE4WgSV5ZRdBzLFgO6nzhJp1ltvrlB2HCoWxQuG+jTvt2GxBWUZaU2mMApZNuSHA3vJpCliRhqqs\n",
152 "ZtvbTrb9ZIk+i70Ut1OcnpgeKskTCFUwjaYy8Jhr3eiefq0HIfa7yC6HOwVyULRuNDn21JngbcL+\n",
153 "E8A+MNnSxb+w59+Cj2tELJBbjEZr8SGwn0j2aLkTPdp08R2OcKV6fXB3ikPH3n8tM5WTfrETtZcw\n",
154 "g3QWH0dH7nKNiMkszqo/EDafaHhJ5Bm6ee4UtdAabxnMcmUUl0SnYx+uVqs5XAGN9QGgdeCrASv0\n",
155 "3TmCsJcOdhnozexD38goK9HXynEKr1OKDs9guhQD039kGySyIQpJAdbvJ9YTlPvyUl3/aLUf34G/\n",
156 "uGxIyXpE37DoLbAHwJaU53t9MRCfrU8o/k4iRn36Lar8Wd5wAfgN4R6xelyy/ssAAAAASUVORK5C\n",
157 "YII=\n"
158 ],
159 "text/latex": [
160 "$$x^{2} z + 2.0 y z - \\cos{\\left (z \\right )}$$"
161 ],
162 "text/plain": [
163 " 2 \n",
164 "x \u22c5z + 2.0\u22c5y\u22c5z - cos(z)"
165 ]
166 },
167 "execution_count": 8,
142 "metadata": {},
168 "metadata": {},
143 "outputs": []
169 "output_type": "execute_result"
144 }
170 }
145 ],
171 ],
146 "metadata": {}
172 "source": [
173 "integrate(e, z)"
174 ]
175 },
176 {
177 "cell_type": "code",
178 "execution_count": null,
179 "metadata": {
180 "collapsed": false
181 },
182 "outputs": [],
183 "source": []
147 }
184 }
148 ]
185 ],
186 "metadata": {},
187 "nbformat": 4,
188 "nbformat_minor": 0
149 } No newline at end of file
189 }
This diff has been collapsed as it changes many lines, (1770 lines changed) Show them Hide them
@@ -1,224 +1,1584 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "name": "",
4 "signature": "sha256:9fffd84e69e3d9b8aee7b4cde2099ca5d4158a45391698b191f94fabaf394b41"
5 },
6 "nbformat": 3,
7 "nbformat_minor": 0,
8 "worksheets": [
9 {
3 {
10 "cells": [
4 "cell_type": "markdown",
11 {
5 "metadata": {},
12 "cell_type": "heading",
6 "source": [
13 "level": 1,
7 "# NumPy and Matplotlib examples"
14 "metadata": {},
8 ]
15 "source": [
9 },
16 "NumPy and Matplotlib examples"
10 {
17 ]
11 "cell_type": "markdown",
18 },
12 "metadata": {},
19 {
13 "source": [
20 "cell_type": "markdown",
14 "First import NumPy and Matplotlib:"
21 "metadata": {},
15 ]
22 "source": [
16 },
23 "First import NumPy and Matplotlib:"
17 {
24 ]
18 "cell_type": "code",
25 },
19 "execution_count": 1,
26 {
20 "metadata": {
27 "cell_type": "code",
21 "collapsed": false
28 "collapsed": false,
22 },
29 "input": [
23 "outputs": [
30 "%matplotlib inline\n",
31 "import matplotlib\n",
32 "import matplotlib.pyplot as plt\n",
33 "print(matplotlib.backends.backend)"
34 ],
35 "language": "python",
36 "metadata": {},
37 "outputs": [
38 {
39 "output_type": "stream",
40 "stream": "stdout",
41 "text": [
42 "module://IPython.kernel.zmq.pylab.backend_inline\n"
43 ]
44 }
45 ],
46 "prompt_number": 1
47 },
48 {
49 "cell_type": "code",
50 "collapsed": false,
51 "input": [
52 "from IPython.display import set_matplotlib_formats\n",
53 "set_matplotlib_formats('png', 'pdf')\n",
54 "matplotlib.rcParams['figure.figsize'] = (2,1)"
55 ],
56 "language": "python",
57 "metadata": {},
58 "outputs": [],
59 "prompt_number": 2
60 },
61 {
62 "cell_type": "code",
63 "collapsed": false,
64 "input": [
65 "ip.display_formatter.formatters['application/pdf'].type_printers"
66 ],
67 "language": "python",
68 "metadata": {},
69 "outputs": [
70 {
71 "metadata": {},
72 "output_type": "pyout",
73 "prompt_number": 3,
74 "text": [
75 "{matplotlib.figure.Figure: <function IPython.core.pylabtools.<lambda>>}"
76 ]
77 }
78 ],
79 "prompt_number": 3
80 },
81 {
82 "cell_type": "code",
83 "collapsed": false,
84 "input": [
85 "import numpy as np"
86 ],
87 "language": "python",
88 "metadata": {},
89 "outputs": [],
90 "prompt_number": 4
91 },
92 {
24 {
93 "cell_type": "markdown",
25 "name": "stdout",
94 "metadata": {},
26 "output_type": "stream",
95 "source": [
27 "text": [
96 "Now we show some very basic examples of how they can be used."
28 "module://IPython.kernel.zmq.pylab.backend_inline\n"
97 ]
29 ]
98 },
30 }
99 {
31 ],
100 "cell_type": "code",
32 "source": [
101 "collapsed": false,
33 "%matplotlib inline\n",
102 "input": [
34 "import matplotlib\n",
103 "a = np.random.uniform(size=(100,100))"
35 "import matplotlib.pyplot as plt\n",
104 ],
36 "print(matplotlib.backends.backend)"
105 "language": "python",
37 ]
106 "metadata": {},
38 },
107 "outputs": [],
39 {
108 "prompt_number": 5
40 "cell_type": "code",
109 },
41 "execution_count": 2,
110 {
42 "metadata": {
111 "cell_type": "code",
43 "collapsed": false
112 "collapsed": false,
44 },
113 "input": [
45 "outputs": [],
114 "a.shape"
46 "source": [
115 ],
47 "from IPython.display import set_matplotlib_formats\n",
116 "language": "python",
48 "set_matplotlib_formats('png', 'pdf')\n",
117 "metadata": {},
49 "matplotlib.rcParams['figure.figsize'] = (2,1)"
118 "outputs": [
50 ]
119 {
51 },
120 "metadata": {},
52 {
121 "output_type": "pyout",
53 "cell_type": "code",
122 "prompt_number": 6,
54 "execution_count": 3,
123 "text": [
55 "metadata": {
124 "(100, 100)"
56 "collapsed": false
125 ]
57 },
126 }
58 "outputs": [
127 ],
128 "prompt_number": 6
129 },
130 {
131 "cell_type": "code",
132 "collapsed": false,
133 "input": [
134 "evs = np.linalg.eigvals(a)"
135 ],
136 "language": "python",
137 "metadata": {},
138 "outputs": [],
139 "prompt_number": 7
140 },
141 {
59 {
142 "cell_type": "code",
60 "data": {
143 "collapsed": false,
61 "text/plain": [
144 "input": [
62 "{matplotlib.figure.Figure: <function IPython.core.pylabtools.<lambda>>}"
145 "evs.shape"
63 ]
146 ],
64 },
147 "language": "python",
65 "execution_count": 3,
148 "metadata": {},
66 "metadata": {},
149 "outputs": [
67 "output_type": "execute_result"
150 {
68 }
151 "metadata": {},
69 ],
152 "output_type": "pyout",
70 "source": [
153 "prompt_number": 8,
71 "ip.display_formatter.formatters['application/pdf'].type_printers"
154 "text": [
72 ]
155 "(100,)"
73 },
156 ]
74 {
157 }
75 "cell_type": "code",
158 ],
76 "execution_count": 4,
159 "prompt_number": 8
77 "metadata": {
160 },
78 "collapsed": false
79 },
80 "outputs": [],
81 "source": [
82 "import numpy as np"
83 ]
84 },
85 {
86 "cell_type": "markdown",
87 "metadata": {},
88 "source": [
89 "Now we show some very basic examples of how they can be used."
90 ]
91 },
92 {
93 "cell_type": "code",
94 "execution_count": 5,
95 "metadata": {
96 "collapsed": false
97 },
98 "outputs": [],
99 "source": [
100 "a = np.random.uniform(size=(100,100))"
101 ]
102 },
103 {
104 "cell_type": "code",
105 "execution_count": 6,
106 "metadata": {
107 "collapsed": false
108 },
109 "outputs": [
161 {
110 {
162 "cell_type": "heading",
111 "data": {
163 "level": 2,
112 "text/plain": [
113 "(100, 100)"
114 ]
115 },
116 "execution_count": 6,
164 "metadata": {},
117 "metadata": {},
165 "source": [
118 "output_type": "execute_result"
166 "Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap"
119 }
167 ]
120 ],
168 },
121 "source": [
122 "a.shape"
123 ]
124 },
125 {
126 "cell_type": "code",
127 "execution_count": 7,
128 "metadata": {
129 "collapsed": false
130 },
131 "outputs": [],
132 "source": [
133 "evs = np.linalg.eigvals(a)"
134 ]
135 },
136 {
137 "cell_type": "code",
138 "execution_count": 8,
139 "metadata": {
140 "collapsed": false
141 },
142 "outputs": [
169 {
143 {
170 "cell_type": "markdown",
144 "data": {
145 "text/plain": [
146 "(100,)"
147 ]
148 },
149 "execution_count": 8,
171 "metadata": {},
150 "metadata": {},
172 "source": [
151 "output_type": "execute_result"
173 "Here is a cell that has both text and PNG output:"
152 }
174 ]
153 ],
175 },
154 "source": [
155 "evs.shape"
156 ]
157 },
158 {
159 "cell_type": "markdown",
160 "metadata": {},
161 "source": [
162 "## Here is a very long heading that pandoc will wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap and wrap"
163 ]
164 },
165 {
166 "cell_type": "markdown",
167 "metadata": {},
168 "source": [
169 "Here is a cell that has both text and PNG output:"
170 ]
171 },
172 {
173 "cell_type": "code",
174 "execution_count": 9,
175 "metadata": {
176 "collapsed": false
177 },
178 "outputs": [
176 {
179 {
177 "cell_type": "code",
180 "data": {
178 "collapsed": false,
181 "text/plain": [
179 "input": [
182 "(array([97, 2, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
180 "plt.hist(evs.real)"
183 " array([ -2.59479443, 2.67371141, 7.94221725, 13.21072308,\n",
181 ],
184 " 18.47922892, 23.74773476, 29.0162406 , 34.28474644,\n",
182 "language": "python",
185 " 39.55325228, 44.82175812, 50.09026395]),\n",
186 " <a list of 10 Patch objects>)"
187 ]
188 },
189 "execution_count": 9,
183 "metadata": {},
190 "metadata": {},
184 "outputs": [
191 "output_type": "execute_result"
185 {
186 "metadata": {},
187 "output_type": "pyout",
188 "prompt_number": 9,
189 "text": [
190 "(array([97, 2, 0, 0, 0, 0, 0, 0, 0, 1]),\n",
191 " array([ -2.59479443, 2.67371141, 7.94221725, 13.21072308,\n",
192 " 18.47922892, 23.74773476, 29.0162406 , 34.28474644,\n",
193 " 39.55325228, 44.82175812, 50.09026395]),\n",
194 " <a list of 10 Patch objects>)"
195 ]
196 },
197 {
198 "application/pdf": "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+\nCmVuZG9iago4IDAgb2JqCjw8IC9YT2JqZWN0IDcgMCBSIC9QYXR0ZXJuIDUgMCBSCi9Qcm9jU2V0\nIFsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9FeHRHU3RhdGUgNCAwIFIK\nL1NoYWRpbmcgNiAwIFIgL0ZvbnQgMyAwIFIgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9Hcm91cCA8\nPCAvQ1MgL0RldmljZVJHQiAvUyAvVHJhbnNwYXJlbmN5IC9UeXBlIC9Hcm91cCA+PiAvUGFyZW50\nIDIgMCBSCi9NZWRpYUJveCBbIDAgMCAxNTIuMzk4NDM3NSA4Ny4xOTIxODc1IF0gL1Jlc291cmNl\ncyA4IDAgUiAvVHlwZSAvUGFnZQovQ29udGVudHMgOSAwIFIgPj4KZW5kb2JqCjkgMCBvYmoKPDwg\nL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMSAwIFIgPj4Kc3RyZWFtCnicxZi/btwwDMYz\na+wTCJ3aRSEpiZLGHtAG6FbkgL5AmwTBXYCmQ16/dJycRcWq7SV3k81Pf76fzyZpo703l1/Q3v61\nZL9bsE8W7ZUBOTpajOR8ycGnKOcHdZ6Tw0KY5fAgojq9Mw+yKA2Lgiv+9WdvZeCVoewCR6ZoCVyk\njHIkewVw0IYPdTix8y/hao0qKvveiHOhcF5t6qJgqWDPRRXlkwmzm92vHp1g8rYzzf5on8xuby+/\noUWw+xsjO2L0w+gk06Ld/zKfPn64wAv4bPf39uu+XeGZwITgAuSQCQMVZbtRlHWt1fYbZRNCIAdA\n5F/mnjAWEFiiEb0vlGNSCI2iELRWIzTKJoQYXSglJU7PcyeEpf9BDFAJWDhQZgXRKApCazVEo2yC\nSOiQ0efhCnANQQsQhRz5BNHHhEFBNIqC0FoN0SibICR5QCjxde4E4RcgELLDVAqCTPQ6nzSSwmjE\nmqOVNoEgkCuFwuvkiSQskVBwSDTejKhJGkmTaFGRNNI2Esyu5PLyp9QkcYlkLpHr/K4J5jK8Gr/R\nuQ9Sc8bxlW1esL1YD6BjermIrTGdHI8VAXm47sDr8unkz6Pj/Mb1FG1c18Nnw6tcyzM/bIahMryU\neCZzUkOk+rSWp2hjuR4+G15pGUazvjgPle+lJ3RyGIPUvje+p2jjux4+G159qSPIZpXl9fc0RykT\nbyxP0cZyPXw2vNby8yy5p6hynVe77vRaXKeDFemDNxVUuc6JXKqfQWkIJs9/ZpMColBaaSmyffxt\nf9qHsZ12BFKZMbIUZxkbEBOHBCw20unEPk49atUtXxlhoITscwhNv5cdJ5TWC1TVO2ghBUkqYQRX\nS1WC9Mw788O+J9S896ON0gXIxBDZqwp4aBUxFQb3puE9CefA6rk/Dk+NzJQcSZLgFZdSzH+IK+Xd\nwXr2pW/1LnNhOaeowZRiusjnBevZP9o8ZK4i60pTrp8vpZgu8nnBevalSQfHsiYDSJekTCrFdJHP\nC9azL2BFsn2W/MaQGrBaMV3kM4N17A+vI0k8JOZEgM2nESWZLvR50boAwoaylaTvBEneMzSbkkwf\n+8xwPYLx7YtYXAafC2s4JRkpW5B5jtvW0gg3mk4+UZSmm9SHrBX9z/WKNxc9fsvXuu7w+ebt2ph/\nACMXFgplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjg3MAplbmRvYmoKMTYgMCBvYmoKPDwgL0Zp\nbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aDEgMTkgMCBSIC9MZW5ndGggMjAgMCBSID4+CnN0cmVh\nbQp4nNS9eYAdVZ0vfurudavq3rr7vvftvdOdTtIJi6QTsnQATdhCgsYECRAWIVFAwAUGWQL6JjDj\nAEEQRJYAvsnNnbZZxjfkzVMExhl7HImgeZBRCIn6BnUcRudB8vt8zqm66QScef/+DqnvreXUWb6f\n73pO2QpNCBEH8Ynq8iVLlwleawdAhLl81cozz//y80lcm0LoZyw/8+zFIiXCQvvNBj5feebw6M3v\n9H4RL+zA9YbzP3ne5v959xPrhTj9QSEC2fOvvrIaXKRVhTj3RDyvXrj5ok9etDjUI8Q5T+Od0y+6\n7NoLR5ee8b+EWLdJaGdt2LTxk9fkfn3RLCFCWSFWbN10wXkbn8ze+XPUHcT7Y5twIzjoXYPrjbju\n2vTJK68pvnny6UJ4QujPvvSCT12+7NTTbxHarheEqC+57Irzz1v629+uRv8fE8Ib/uR512z23hfG\n2LWtHM/l533ygq985Ml/EdqPMD/jbzdf8ekr77zla3cJ7fVpjGHW5k9dsPmkX106T4i1eK4NKd6I\n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\nc+tTOz5911Weq+KfyX7mK9f4ru2/9t5rv3Pdjs+e9Lmxz09d/+ANX/uTxTce/8W5N+Vv+sub/vam\nvTcdutm+uf/m3bc8sXXktk/dduNtk7d/4kuXfelzX/7Uf3vov/3sT/N/etmffvtPX9n2uW3T2/Zv\ne/eO+p32nVfe+fCdu+985c5Df9b1Zz/88xu+kv/K1r84/i+uu2vwbnH3GXdfdvef3f303b+455R7\n7tpe3X7a9s9tv2P7S9v3bP/ZvcvuPePej997yb1X33vjV6/56k1fveOr9311x32R+/L3dd83et9J\n951y30P3/eV9z973/P3x+8v3998/dv/i+z9y/7n3X3j/p+7/wv2333/X/Q/d/5f3P3v/8/f/8P7X\nvrb7a9//2itfe+Nrv35g9IGTHjjlgdUPfOKByx+MPJh/sPvB0QdPevCUB1d/fcnXV339Y1/f9PUr\nv37DQ2se2vjQ5oc+99DWb4x848RvTHzjrG9s+MZl3/jdw+Jh8+GtD08/vPfhAw//7hHxiPlI9pGu\nR0YeOfGRiUfOemTDI5c9cs0jNz1yxyP3PbLj0Tseve/RHY9OPrr7sfHHTntszWMbH9v82Od29O6Y\nu2N8x2k71uzYuGPzjjt23PH4xidGGLbLSFJ4/gGetwHbPiBGW4PDraHh1qDd6p5udQ/vSvvebQ3Z\nrebeXUXfu+KvvFqXb+CvmloO1KdpvoGR2fPnzUn19MydPzY2/yTvvLndjXog2DM2Nmc0nUryLwIG\nUplYLabheG3BPI8VTMfsZNg3VKkMBUaDp4yNLct1NwOB5w5t1P7hkLjq5JOvii3IWaVYNJOI6V2z\nB+eEJhYtP7E6r1FLJOc+7bn4vbs99703iiELoaJ1z196P+3phucXWhBe6XXEDh9qX2Fo6yYXGisN\nzxbajS2TO6PPRT3rpnZHp6P7ot51grZmHe3UOhqhdbQruETNkdlH2r240+5G2e6YbLe90NC2jFsP\nGDuN54wfGK8bbxuBde0rSnxSkk9KO0vPlX5Qer30dimwbmT2B4zzetneQPsKC29xgKJ9mKdvcxgL\n3bF0RoVGZs73nk47fyvbWdleFUPtK2KofQPIlIjZsWrMu2Vqd2w6ti/mxZ2aXavWvKhUY481Dc9q\n07V9NS9ewS3RXp9kX8Vj+/pop69/lH012wvz6Atk3dQD+Z355/Jo4Yq8bKGCFg73qha8sLDCczzs\nbhgxxID22XZzwDvQHhnAyzZIa8DeJXzvtu9o4qWRJu+CtJr2roD33ZawW8Y0Llrl6VZ5uL2qrK3b\nFfO+264ZzVj8uPbmQfTXEkvXtHLDhV0586S18qIfF/2Bk9YiAHm3beT6UbVlDO8Ke95t5exdaY3v\nh/n+wRoHqU3u8D7t9axrT3jR/R+8GIgewtm9CQjPNcmtSTw6QK5cTHIvyYEUL0nGiqh5C2Y8eWH1\n6ipqrq7ixltVPHqzAbKH5EddvASZWt11YdfVXQBidc+FPVf3gGcv95JnZ7Hrb7HrpTx7lGfvkAR4\nGeZw9kdxuYm93wMyeW3yNg7sIG9sSrlj2s+ON5G83HD6bP+Y5BV0M3/O6EkeqmZjnjqb5Wk0euaM\nlj1U0VQamhrBnR239ywZLZ17zp/fmZ/Tl9crJ865feKfBs8Y71504qlnx8YuPPuVxXZttLFsyYlW\nebhu9PaWFsf7l4wef2bEE1j3kdjiRSMy0x05/C+exzx7RI/nlnY87B1oxe2WmG6J4fa4wHSmhbau\nFbZ3lQDnql6qXh8Frw9KurBvZR+mdn2fi24UgEZddP248APddiLqJ7KJ4VbU3pXV3m357V11gNvj\nj/J+z3B7ugdNbuiRILff1HBxWxBkbYhnJG9S59eS3Ebysk2wqD5XkXyX5FaSt0im43wAMnlbYnsC\nA3wGAtJ+ieQXJE9SXp5JvkhYniQsv+xgs5ZkO8mLJM+S/ILkSfkgDfIMyRMkvyJJ58CjN/KUMJK7\nSPaQvAMyGcin8zBpy+XzAm48WpgqoNv9Bb5awKvLebacZ29SOMcqyyp4flfVlZE0xXQ5zw5SPFZ0\n4XIHdXAtyXaSHLVxBcmzvHy8G+082/1SN9r5aTdvkLu/6qH4HiRvD5CFK2i+9pCPL4Nnk1fHbolx\nXOTfleTfGyQvk3yPPJN69aLLp8lnUi+mUH1H+iiuHCS5hnM9QHIKiZzpAVoaOQmpcPs5kwuaZEdz\nqol2pjjMPSQHMMxmxNuoz4LYn+SBV8oEZ+EyAtEve6gN8z2PxectWTm48tbzFyw4/9aVi28aXmh0\nz15QXHLZqb29p162pDh/3nByc2GkkVxw/tbTT996/oK5Jw7H6nl79KwrPvShK84aDWf7KlLue6Tc\nr/B+rj3YBVsX7BqkPAYhj5C+VmRvexvt+esgraDdSu5t/5oMKEeCqDZufLX8ZPmvy39X/mnZD7GE\nxWv3gbS67F3zYRHhkRdPtxYPT44vXrUYIjC9GM/KdmvF3vaqU6hFp9LjnbryVCrQqa4C9UFn+lwF\nWoGLFVCglrm3PQLMWrG9rRU0se2hvhUcKRx/n71rFBq1wt51IjRq0Yo+3l803N6wiIqwSGnU3Vnq\nRw4dXly6toQOl9Op7KhTikjWkPPLwfnJH/e/1Y/nPxogSiS3knyP5J8GiTDI1L1DTww9OwST+HdD\nFCySF2bh5SdmPTsLL/9yFqVkmD2QvECylmQ7yTMk15H8gmT/XLw4f+7yuXD2n5l769y756Ldb82j\nJsxbNg+tPTqPtUhuJfkxydhxHC/JrSS3HM8qJMtJ7ia5ZyGaWLvw4oU0vQupwCTf5t0Xx18dp2qQ\nQ78iufpkvk9yN8ktSyinJHuWcvJLqTiPgIWT382+nPWsm7wlexd+2reAoe0pcvXu3GM5j6P73yO5\nDm65fTEjjM+SHMPuZ0jOIc9vo2aeQsbv6d9Pxr9BTr9MckuH8W+S8XtIXiCrd5DVz856iaz+RYfV\nB0iu7XD5RZJzhwnK8LPDqLlgLplCcoBkBdl+7dzbwPb2VrL0aZIVJK+SvLWAsBy3/DiPw+M3XfZO\n3nr83cfj7pvk510kU2TqOQsvIqsf442Xxzl0krfI3mvI1AMk20m2krMHlxCIpa8u9azzZ5zgEy6t\n3jM/PWd0TDo8hqXzu3v+uB3I0Ez0aJd6QjGjPJyq9SXnDtn13nSvL5yMRtLh+Nyh/pP/MxtxgrQj\nhnGi5vX1dGXqqXC2K57M+SKWHvDHlgdixT9uP/ppXzQZjq8G+RbiJlPktMF2IgdLspOicT0I4xhG\nTbthQ1sJGSu119MiPkAiaPZ3F1zlj0DfI67yZ3GRdWKjVsTeZWjvUpWfZqxxHMnjJK/KIIihx708\ne9pHFEEmt/se9wGPp+k8V4R4I/R4CDde5Q0ZNT2l42yCZAfJcSTbSV4l0XVWoXtYTZcg/cKt9Aa3\n0gSuliEMyRRN/kSaKiKjomUkMipaJsfCtp4g+WuSFWzwGZJl6U6YMyO4YVTztS+f/pmV3d0rP3P6\nlyd+ufjmSxcvvvTmxb9cPPv0i+bPv+j02YsH1968Zu1Nawdl7MKYtQHeG+LClne4bYMT5HfLa7e0\nva3AdCswzNg0NN3S7FZ4b3snvN7k9dY2y+PwXAYpLs89uPC4PEeQEoBJ1f0emlQdYSkRmF9L1WI4\n+N8O7bOHPqQ9dehO7ZxDjy9e7PnO4t8sRhwux8TcQVgyDl8kdiEOb3DhZZ2YfNs8bHqcJAbpzBZ5\nWyY2bhx/7Psfle/Pbm8D36aG7YX2StuLBMl+zvYwiKcf57TaCxl3ro+iybejsrVOWxd32too21o3\nrg+bC82V5nrTt2Vc32Y+YO40nzN966ZeNzk+mOAoh7YBo5p6Pft29nCWt7JIlvTh7MLsyuz6rG/L\n5APZnbSDG+hdttH/PVc+ut8jc7he9jugHOqGKMVFZk0yf5JjXs/RHybZGXV4Ad2yHN2yRU27vV2o\nUbdoTK8HadUc3YICtQqdPMSaJo3sxeNWXNLkdHs9g+wHSEQDyZtEOw200y70VVxUXejTUt3aVrpK\n6K3hXTYykth0y2Jb1MIc5GzyOO8Kr8dRvJ+SfJNkAcX+HpJnSHI+1FwQmoDuTd4T2kEVfIYqmDta\nBaXi/ZTkmyRPZ6hkWSYTtCTdjDHP4dmt9C6r6VP2k3Qjf23fyrPVZbZHEHY3yN3JjjLOl8kKx3IX\nyQL2vp3kFJInSBawz1NIniV5hr2fxd5XEFrZ8RSbXk7yUfQ0Q3OpCMxTYh+owZrn0KGJFSs+QI9/\nMzamzXmfLhvAWhdntzTosuboMjTXu5eYQp2h18G97ZWGazK9gM3rYihwIRgvee1dPuAX9AoVz+0K\nUXXnNDqKO6E9eeh+7ZRDU1JnnRzovyMWbHpK7WQJOVDJ3hWCrR5OgguHafJaIK2kvSuGESXtVhPZ\n7nB7hE681eOOpo4B1I814G1Rz3IYYrhVt3d5IV5Ze5eF4SXU/cRwex+8w664MvAvIt2a/Kp4UjBE\nwXn72yQXMW5fQ3INyNRt2nbtcQ06+SJv/YHkpyTfJnncA/J3JHf5Qd4hCfghhvP9y/0Qw7HAsgAa\nfyfA+wHMbxnJVJgeP7w8TC8e5stcOtlD8g5JwEALy4zVhgcNGcsNtkDLtZqG4i2KZR/XGQ7Qr/XR\nr/VVQNaSrGHM38c8Zi2JTLffYArwsky3mQfc1XyUecDzzF+ealKA7+a0d5C8Kty57yB5gQy4WLtW\nu40MeIa3fiIfcsYvgkwe51+BebaXcRbzScY6U1lOspajPSjTFI52dSfXeqOThf+MA/kuyaMke9xx\nad3dR2KQsfnzKPiBwMxsxXNp18bFbpgx/4Lex39z4rZFbq5y9mdHPIu7B91AopD5P4sPPdJounnK\n8IirB5+SPu3mlgE9AOPbq0hGQHaFIX+e6ZYhFWE98xTvNLKTXQHfu5PCsi1YpG10ctPWPji59iqL\ndtxyJVSDUGquhIZxEaaEejSussD9Udd808j2W8HplsfepVMmE3NitdicGLQn1tgwod04MXHoCxOe\n7xz6e23OeydqKw/tUmMWOzBmrzgNfUizvI9hyCrfBoQhk9f7twGRqYp/2L/QD+e12z9NhITftcVH\n6bEcJMYlVXbOjgl0Rp+yHMwJSJ+SdvyqCZ8ya/IB/86ZjcPF+g4z9llIc7feRxfrnMm1vcNv4+3c\njHY+KtuZO3l9cFsQrz0HiziuV0LDoYWhlSHfFngqatBOkvUkb3NpApzn0iPGdfg3aCUjfWza8bGm\nXOO7Hh2ORx/w7fQ95/uB73UfhxVcN25EfRXfsG+hb6XPv6W90sb4rk/Lmumd6efSP0i/nn47fTiN\nmno0XUkPpxemfVvc2ID/l2r/c8bYr5d9DbtjFxhVezMImBA4TC1fSC1fTwXf6Zw5vlUTkcP/on0Z\nrE2Iv2mFhuW8J18PvQ0X1UrslZY3BD/IJT/av20pV4ak2LhY2biwpZWzw8rKyQWj9g1cNbKlvaNV\n6wXS7YvJvetINnEsB0CmQoFsoDfg3dK+hSHMLQwH7kGYOfVM/MX4q3Eo+BNxWoML+daFfGsr693m\n1ms/DTI/nZb+CEIqk4junnPCYyM9swvhicTwacet+IR559DcyuyFNe2N9w51nfqh3lNXuHp2HeYf\n0f5HyxymOp1MZP+K5DDJn5NsJhkHS6lnCDHPhDud/Ib3r7gO+T261rWMvu/xUmhS3qZ3nnepF7HR\nP3l/zhpfZI1fkwhUa/n2Tp7v+zQ1IuVr+qCqf6BkjlFGl5J4QcajN/ju8D3oa/l2+6Z9+yAyLVPi\nwDWIwN72z8i28wOfDnwxAPb8L/LkX0m8AHnqjsCDgRbvT/OW3whw9XQZjX+vf4EfpvtW/93UvEfJ\nz2+B0JBEptsVimHL/sBM5CjdNHBhBJyLIC6CEnyv4bg4fW97KVMHv9DZdQ9xf4qdcRDtFEkiRNXR\n2j+hwf4Vyd+TfIdc+g758Sbrf48kxPovMkTZG2Lw/LLnTQ9G/12/W4vpTGLOHG2OpjW0RiNGe6Hp\n2ocvOvRV7dpLDj1saBMT2p3anEPPHfq89slDf64+4pHYa7/FhV8cd2ze4NlL4xcc/oD8QHKCQaLo\npALo7pRDl08w+pc65bRrib9GE60omqbowD770LqYbvnYQdtGxNuK2k6CAlz1vaTGtIDxg4LJ3iz0\nZpnHsnobfV1FY5QP1zZurA9fEb4+vC38QNgPSQurtVrY7bbQiMDU82KP2C+862Dad3lwO6RrBMYr\nQjI2UpGSIa8mbzHugl+HxZ+fCjJOmhecNx8zfOUVzvGMMya0S55d9uzPFu9ftmyZdo/LR2+eOuTJ\nt4MhROcrGdeupBkSoaDqAdFbex/BvYFkFUkLRHJE29teyAmtJ5G+/FUQGB6ueT3H+ELu+2xzcySp\nB5G97T00AFMkZ5KMkEQ7aQTzHynN7etJHiCZJhn/YAkP4SIk5ThCPrQ/RQv2TyRnMxobE8sQjU2e\nLM4UUNm/4v19JLtp4yLINKc5YN902x+K8PXvQzInv+y/j4r2WUrpkyR7qZG67GDyy/p9Olr8vr5X\nZx0G3U/qat7GdHuNrZbtnmInF5Mp2zWuuWovalzN4o0nSG5Ci5M/CrwBOz95QeAq/Ew9EvhW4LvU\n/7uCNEhTweeDe4L7gz5EkLRjj5Fsoj7tcNOAcf2Z0IuhV0MHQ6j0uM5lGf1VjGrqEv06/Xbd62Tu\nvyR5hGy+kOQukudJ9pOcE6GRfpDjvZPkRyRTJPtBmglGDw1qKBVU+x9vXz7hOSy64c4mLr/JM/7e\niZ6N790nj+84dvkJxj9aue3VIVNVWthVTLlu8N5BqzrtyhAjfQ8kwj8NRR2PrfSv91/hZ7DBmOA5\nf2hLS0ccjwoGIqbh8cSIMW6sMjYYm40bjDuMB42WoW9hKr6F30JsmVxlbWDMdD1czBTjp19bmH6r\nEzxJ2/e+3Q3hp+2bukBcJW6GnrX/gBmPW7rIiT5xnFgh1orAlvZXeNN4EO3sFtNin/BLw+uZRljN\nvZGpHwReD7wN3MatSwLXBW4P3Bt4IvBsILCu/W8BtuYPpALNwLzA0sDZgcCWlp8rGiOzm3MYlimm\nejZ4Js49dC7IZZ41YOjH33tI2jonF3+C+4KiqvYFNQsxQ7l9PfRpknk/pjxuyg1B7uwc7pMhgoc5\nkTeOnCgherTftMowSnvbgjtCmwnsuJDr2bvCMuvelUSyNN4LHrb6dnNPaCGb2tfHvc0+u6/a53UC\nvQbY1nB5KDcD6Uwa9i6/Jjf9oipemKBHANnSPo5n20kOMrbXPTkPlHABJeAAyQqS7Z21MGbm7f+Q\nZ3SoaUY+1IUpqsE7QeCTDjIVCi5nvDRGLXiUZD+jn0AoHeJuDW88RbKc1mwZjc+jJPtJ0hSXp3i2\nnDIzZi2jzNxFmdlj7bfegcxMBqw0A/F3qBtpbgzn6F8XcBFtBcl2bvq+GjsY+0MMtfVYLobaE4xn\nQDBnnh0kyfFyNdfYbiVZzcz8VpK1zFy2cpl5LclWpi9rJeHyyGrmK7eSrGaGems30SVPJxd4J6BB\nkwuCE5j/5Hxzuckfa7nFn9jyGH/iy+OedZpcg52x3CpDKzfPKXs832GC4yY6/P0IMxw30+Gv9gkm\nOW6yw18mOW6yg1+1xrMQPuRG+hDR0FbBMLcKeyd3Fp7jNtnbmKVc14nYuxJQ4+g07W1yr9r83paU\neyLt62MyNW/Vp5GBj+sLmyub65tXNGHPtjVd3a1B1Gqu3KVwkaLc1eRGJP1yCiLMhdbptl1L0W/Z\nw7tiShb3UJqWM+y7yPsZMm++bznzi7tl7Ea7KDPNu0lkfvkYV03WSMKlmR1yC4BLJ0+XicM1bO8V\nkt+ThCixUoov7qwfbSc5hWQZ25+vu+0vZfty/+6AlAJ28jjJQRK5JrTf7am9AkRzMPTNmZNwli5d\nEHHqCR239OrVs8O5gaUbFi2f0PKH9mujhxZd+ufr+k7+5JeWa9869BPPjc0Vn1yeOmHhwtkVbeXi\nQ/+6eMmmLxy39uY1A1zrlDZC5iN1lZNpfcyl2pt7wa71vVf00rb0chdZ7p7v5P7xepqJt3sP89l6\n3ljofILwAe19VLY33r6C5mQVv0XYPICW7YHqgGfL1O6B6YF9A9Dp8UF+kaE2pllpIfdN3h5Ql0e3\nfXGn7Y2y7S6Ob93keO+qXuggx90e5+bI+NxVc3nj+D86tuvl+wva4+hx8sGB1gCcphjg0JDOTA/I\n+TpDwHwHDg941HDk6GQS5u3YWENkxBz/1nahjzGUnGwfQsQ+Z6GpNbq3PTLKmG+U4yMRvNwsz5qj\njCleEj/hmtFlNM7XkjxDC92n1rEMWaf9Y4rPfpKrQPi9Rtfe1qjdmrO3bXbNYY2rXDs3+V3zZXqG\nT/DGPm5dby7cQJ1s0fKMcIVnFQgXXmn7M+r1VyiVnyWRS5j7SbLq0XXcQZvKPs8l43+mtDbU/a1c\nDjpAspGkW430Rdqtq0hmqxuXzGZ7s+lQ5tnzqvPA44XcJmzN281twn3zXE2fBeWe5Wr6KC5Gj13j\nlRdduOjixSy1KFeVvgeZDL9JmHxavEBmXkI+XkPyBokR9XIoL5OBt5BcSfIzElM9+h65tdV0lfRq\nko0kGdlu+1Uy5DqSZ47wZxaXmSefyn6PrPm5ZE11Fmt/iQw5SHKBZI26+8IR1sg3FWt+PlsFjQs4\n0BUMW7eLxzmHAwwVT2EA2a8dr0Gk5zGpkkuDexioOquCQX8G+WH7akapexhYzg8s5wLCvDBqd4NM\nPhZ+iouDTS5FPcU5L+XE/oJkzFkJXDf5qDlFqemmk1xAMs864iSXcTHqMSbwb5EEeXm86xknD8R+\nz08Qsvw0SnrJV0mO4yWz/PbvSbJxrrzHV8Q9joc8TjrMBMhWesjHSf5A0p/m0mPGtcdvkfyeJMSV\n7WVcUv8FV7abXEOXS+pyIb3JhfRz6hjPssbqBnr5PVnfz88u3uFKZaCZboJPY/zcYjlJoBvkGcLx\nJMkabulme/iBEs/WUOG3khwg6ad1WsO93P5BJv0jnPwIxYkYZudws2DOxByuDMzBDR032v1zaNxu\nJq5yUXSC5DgivECbYEbwOME9qP2B57rGJvwTzD10Ap1n8r8gMEEsZ8I4RQR7ieXZBE8GORK1+YTx\nbvMxwng2YVpKBB+1pojgft4I8IaKGdoX8UaaGP2YaP07yV8Ql38jSREtFU+0byMoa4mHnwA8SnPw\nVvbfKfMSjK3k/lb6rbVlcr++uo5H87lX/pbcMCcOEoztIJOhZpY4/IFBzg4yPtTB4fdk/FqSHHE4\np/Mdw1skq8n9/SS3cjt9WQeCU0Amb579F7M9R5Z50/yjMs7XWD3znQ+v6t093Jrudpd852c867o+\nfjxjoEat0TkbnTXKSGjpNcOnNU9zzj8zclrTc3q1wWDouE19Tefsov6x2Td+mFHRQPfp9TOc8/6e\n0+sdv/PRjt/5R+l3CuOGvbS6dGTp+NJVS/0QkPX8WOHw0iN7Z4z7M3JfOqPV2rEMPIudgcXO2PIr\nUTHdXsjAKaZ2pZ/jhwwLcyv5IQN3rj8gTZYbZkx5UpE0Q6TUcPt17gHfAMIlkRnb1Ecim16SFzuh\n+SWd3bJNDG96GaRfy7OD7m6Zyk97GXkfZFB+QP8909GQntV7dVj9axkMvUhyK1P6W+T6YDfb/rFX\nGlqcXc3GLiK5lo31sbFLeHYN3+vTIZU/0X/B3LvAxapbbK4izdyM5rewXE7aceXIyb3xeO/JI1dO\n/MNln//8ZbdMaF9K1obyuaF6YvHH169ff+gp8noEznwAfjwl+rTX2nYAvJYrr6uYfxzmOIdp5xIB\nW8aWdiu1txUADghtbXtX1fvuZGtgNwMEMeAuiR+VbbpL4rsKYHOCy/+7morTa+UaJKe6lROUn8xt\n5SzXkqymet5Kspq5yEEujDxPHf2Wq57tR3nWzTO5v7+C5FF+ITeWXUbl3E+bmabKnuMYTmQ7OWY7\nuf25d3LMdnLpnGfL5PLcOfhpp/Pg7qvFg0W8+2Pq9Aska2hlV/Bse4nWqvQHfoek4+7kRHlNGa8f\nV15Rhh96tXwQP+013DiaqPMl2uKD9T/QGuTkjY4NeLVxEBZ6Um/kGug4RxudphVYRt2/q4dj7Nnf\n804Px9iT7kGdc2gQljHI20+SZii6vPcchH6i/T3yRXqa/UypfkzyFY74RyRvkjwPUqvNyILk95hz\nNCdHmufkTN6BQ5d++IsbxsY2fPHDp+F35Tl73juze2LT4kWbJrrxu2gxfsfOu3nlypvPG+Pvhu2z\nPFrfCZeeMXv2GZee4Py6Ony81OG8diG0kf/zii27LLWWGJHrwc9RzihsuxKQpoDdyk63ssPtP9C+\nhrLZrGdLK7e3naeJ/SZ1fGVuPXRc/Wxpv0s4TT48nqQPREpl1m5l9rZvgLkej41nVmU2ZDZnbsjc\nkXkw08qEtrRX8mvaneTQwiK/qChuK7pfVMgdAVdu5Rqm2h6wnBViWxoJrhnkudUud9Wzclc9T9U9\nwG2ji0PXcqf8dgpznhoql5+66WbGKKkX8MPaq5O38AvO5SkqPHdQLDW83ZnpzL5MAAbAzZZF+0DI\ntQWyzUtJDrDNiwj6VjQ31Z86PnVKyrtlhiHgwor6LD7R8DZ23ODaghsmfnLZ59et+f6av73miDV4\n7wue73x8/SkXhA61NLm/MHr4X7T/gE0Y8TzQjvR6B1q9dmtkb3snfc1hkitIXifZNkIL6n8XVXYF\nYYz5HTnhTe9t/wAz25XxS+NawaOVDPmvINk26lrpIXB5yGV5AhcJyfKhhMPyIbX0G1Y3wsPtTGKI\nZ5lhfpNEGMJ2q7F33NjZeK7xg8brjbcbfhlMbu0kE9vlAtaT4q/F34mfil8K/7r2e7y/yV2elOuS\nk89qLzEKeZWB5TJ9NS2sTF5Xd9ZQHqExesPmd9j21bbH+QZ1D2G4h87k8RTXJJ9NvZT6SeoXKd+6\nqQuzV2dvyXJp7NEs04c92f3Zd7KA10eBZYY9uaA2UfNwJbP2Yu3V2sGab93kpu5r+P3rq4wHXqE5\n+AmTqq39FK7+a/mp3cF+eiKSixkWHJRf3vGzuX8HmXpk5Fsj3x1BavnmCOXndwy3psTzDKi5pKk4\nw53pqae072k/5lb0L8mFPXKvQ3dnew7JDhnxcsqb7Gsw5XFjR+rp1AupV1IHUn7nc+Pf0cpenSWT\nj0wTDy+Sn26SBHNunLqgRhY9XXuh9krtACbbXsE1n2s41YtJftKZ9B5O+mXO8UKSt+QZJ/pjd6Lt\nx0a4q+2uErjxjbulNndWwI1ytJ3D5xbHBvJjq9avGus7+cz+RVf1LcqcsaAwNlCszFm0dNGcSs+i\nMwZO/ES/Z+XSaGV2bWRevTB0yvjIh+cWZy8Y7hmO1UYqzdm1dLo4sGj2nNNGs90jMq+WeiLz6iEZ\n35zz/zH2JvBtXdeZ+FuwcwMJYuUCkCAAghQJkCABQqJIiBJJUCtta7cZsrUtWf05lZjEizLJSP80\nsSVPMtK0iSylnUj/NNqcTgU+w9DSzkitLWpJfyMktTYbrdjakiU5E6mNrcWVybnfeXggKSnTOtHB\ne49vue++e88963e4nzD5poqUW6ZCQzC+BdKJQT8ItZcRknLI3yIEGX/Ucs+8rVUJqvqEQNEisqvs\nHL7DIEgnmMju7O6wtBlbRr2y1KrYlFE9EkWikhVDLeNNVYwVtFaZ3fzc+P8Rqv+P8J2urodlrAru\nTqKC8We2oiH1Bvy5Asu81InP62RMSglQKkpLuxEPvQnkOIK+O51LnMLjJK5ytlOOuVxWDs9Coiyg\nWMYoiDBQBrcVm9lFheX4c1FA2sZW+JF8WTS4kbUnDUvrFAkr+YLuVXBW4odyPJ8pO8A46RrOfznn\nkST56YUc47wJMlOnyAl03VbbQ1F85skoIDMTnso7mquqmjvKvxGP75mxMOJyRRbO2BO/pbE319c3\n2TX/+GfWQG8w2Bu0/g/2LZdO/EZYzfqygh9E3MMSJe5hJB8GfGOiPEPpLtK57LIzLN3CFq1Cg9jF\nUjRSoXqQ3FC5GaLEbuchxNJ3UpoLyDmQfkgWLqfy7fNZF+c/bNQnW2A+eyTWpeQ+IQWvY0QxQqf2\niSlxVGRSRUTsnbSmpg5qj2rPwMRMxuSDuqPo6R3sgySvFd1BNpOmyFLkLWIy7PIiJne8ZtwB/ncV\nrG8HFGBLsRd2YAtWuFomqUu7sIDdALFjdwvYwC6s63abn63ryRv2+2wpT+ntdrvfzm67yg5N0Qs/\nGMnGtGBSSoQH139izX5qXrHlwmNeqWIfUMU2hdXmmc8v6X9upjleWuX3ewsLgBpSGud1M55dGoks\nfXYG/9fjC0N9zRVGtdpY0dwX4pOYv/TdaP42ZeMykHdUySVvVU5AlOuETjcItfpQdkvOsXr4OjkX\nrCF5qPI4LluCKzZU5xKVboEcAukEuxusUnK/5Pusy91Hzv2aGSvaXYlbnau8UomWaJVbohFL6rBV\nR2EXwUPB48FzwSvBW8GJoPbxbduUfSfpkCv7bGpF8lbVRJVAB8CQ+IkvGT9YQ/zo7tsoIl8vcWoV\npqaK3KAxWJET4gk4scgbGoTIk4sPGBFExJ2CdXVCcSgCWQL5bhvIOQh5EA+CmIUxzEcXuFkRyDaw\ntD0gG+DEG9Pf1isshXzHyhAnXkfigQr+2eRT3LNY1JbBsdML8jJWtu9ivftj7qccllXFaaWiNAiB\nZDXSOJar8XWu4oLlIMjc8YRMId7Nh/hG4fri8V/Hx3/bL3ukyD8Oo2eCbRYJ+ZLI5GTpCibVcUbA\nuAsyUhFsC3KArnSOoloLwNDYS3MF+TB23aNoMJDXQUbJEYsOhIs5uV3cw/oWbnxdBt00kNyg24xp\neIJtj+jZbVR6cvGeZu1PtaniqpUqNmG34G3ugmjB+XyMwBerZUsIPKa9WtkNIRkEWPlSKw0vGF41\niAMQXQszUhyq1QlGRorYOXsw8wYx85Zg5lGS3zaQEyBjxY8NXSQuRF8ln+yI31NsPNJ7IP8MopL/\n9F00cxYImilHTPyzinyhiCdgXEuflgwiddZN+Ax+QSFwjKTMBo+h1SAO49Qi+ox3cWMrPjtZleIQ\nYXQILriD76KBA+4TdO79XJx5BA8lJ0UbRJ17uTANCvEhh9o9WlwwFGeB3MPzdTAj3sUHjYNEQWxF\nYFd4eoQNGvxPdNP/Ql8I0nJJOND/y6WSIC39Zf8a8md+ZYpfk40lDZtrG+AnFo6Qnzh5SH8cAudx\nTIdbmASb9Ntw4E204r9heJwQ05h6nB49KQd7yGEob4HsBAmyd07wmVjRNn43f4g/zp/jr/C3eO1A\nzNTJL+EH+fX8Jl75m569E7pMy/PUqaqM1I+uuYTQrwJOZVS5VEFVTNWv0gxL2/GR1JlY8aSD+pz6\nivqWWjcQMyN27WH3tWFY0sgt1WM8x/KUoLRBnZpJM+jlQZCLOiQoZWKmoDam7dcOaTdoN2u3a/do\nE1o9womy2ye0ae2YVjuAuxkysj+pE5/lArb2InQkj7Vu0jd+Ii+dN5bHWmc15rnyHvWd5w3Lgefw\nl0tLEHR4q2ACE9cJw24aR4OPd55PBg7lgQlJpRiB58Fz1nAvgx3tx2i8A6LBn1pBvpezw8ObDomA\nT0saLbzvUh/jlMkPNZ/CyvlzWK+Pac5i2w8OuoLCozhNNhxFnZb0tIMJ0IvB3oOBfXj6OF+Bca5H\n9HavegUs42RN1cB5HNeu1LIDGnDhVSB3MMA0GHZtIEcp1QFb5G+J52GYezjEz3LLEUJiQ6ueZoRn\nQ553i6KbF0N8++jq27xq8NLl1bx46/f4g3zZeGL8+/yc8eP8N/h+GvMT/8rG/EI25nV8YUIISOfA\nONm6sg2xECqMABpsQ6oNKiWITP+4gDKBoiIktSAHATFFH4GkGnaDTs0SzaBmvWaTZptmt+aQ5rgG\nN1C25TAFtpLuxpAZBDmX3RoGHgVblUA2G5Sv/ljJWlKrEJgtdaNHl6mxCH9P/SP1XvU76pPq8+qr\navaApWqEy4Gj4St9gkmFeEGOqUfqlHpUfUF9Ta2W45qlN9ktmITOh0xs6WEi+vjd1X//96vH7/JN\n/J+MS/zi8a9SnCb1Ha3p0aycsp/yMvAaTFjRT4BXdOZ0hEOK8pCNvcxevy53/XN0fTDLdlJX9LgF\nEwqL9E49E84OmY+bcdh8yzxhxmGz0yzIgZw8Z2X3MiPWnbcwCYGtg+vBRwN4myXYWoLXVyOJhX1T\nPsb380P8Bn4zv53fwyd4+qbZ7RN8mh9j7AmahZBGDC8i5f/DXxIPoXA3aQM+ZD9IEGQMC8Z2wx5D\ngi100hUM5AkQJ8RySqufjMKn+KmHg+QQPaol57qkzQkXPhDMa4rcQZZNWl447CBxECwm7JvziD/j\nq1qrhKLxZ/k/Hxf4n4y/wP+rsOXLY13tQk+XHNtC/UjftH2K7uiltkkb8kh4xIjszI1XRM0BJkWJ\ncfmM/1/8GGfkWvh/kSoDYn0iYBxRs7kxATHRyQRGBLmUqB8kjGn2p4Q1nbAGpFtMkkaatDstBZEu\ndyWM7glPS3I3PJTkPhn+ginQIme7twSS6ZaxFmFghBMeJOqMSu57qfBAssinWNjjLIyjBS0xC3w4\ndS0Q2z70fuoVyEbzEha2i+InUETe0Z5EWMsdCC3Eqi4WfAKGvAXK2veQuPuO+SQblckd5n3I36UU\nrosgv4V35im4zE7ClJansVgsXkvY0mNRs7tYPsGj4dxN7ijbB/1zH7SuN8lOCkPqZbhSboLUBvnh\n1NbgruBBWE/s8K7YmnCoaVfTwSZ2yM/2kkeaTzezyeFvjjb3NYvD2aCI67kwHnqDD7CCfApC7f8c\n7YSNKAnDCRJpcGCFBeZmyw008IJVaRSy6KUbcOxfbrjRIGT9a1Y8OtU8yh4tWZr5Yc+U+JbZYou7\nWusLkwILx4/b6211T4nt55+0L+huMrl8pTWtNcWvPjm7tuu71Z2N5WoxJopCxZKoc2ZD2axVz9fd\nUJtq3dYqs97mjzirw/kbI4F5pf6O+l+WzTIV15oC/mJ3qDo6x6Uj3w4bf8J7bPx2ZHnS99nAtklc\nmPVbMAxtIXwizJq7PTwlDmH6NU/TNW6Ji+IaJGv2Y+tEFPJwdE8UWWK3WyfjvmcJLdwXFKu/FGtI\nERN4kseFc0zFBbvRK1KOajglizpMzuUysl2FsR0RIjZUmLQ4JmoHuG8xtm5jclSySHAKFDzqjoRe\nnvXc00LLdm5Ke4/l2vsctbdG2gb3/ZXWW3Df0ywKIlt0Wy+O9t7qFSZjJD4Ta9gcNXBl3FKxTXoq\nzPhl7Ck2A58ywmgqDWL2tYefwmxpD4wY2GQNG0eMqgeJdmOijNIZytPs5ERtOlEbSPgyUmM7TpZW\nNbKbhI2J7nSiOxAr7u8e6t7Qvbl7e/ee7kT3iW7dQGJeJrlnXmIea+GC7CULMAhB9iOBe9vy3cux\naiyHLrac9frYcoUJLGZTfbHCBOJsJ67sNLGdJoUj1LOdeuwsZnyHzfr2xU3yeyQ725e0s6nqbA+0\nC8MJQzrRZBwxC3ipkTL2w16p3jhSzS7xLa7P4ig01i9GI3+NtOAP8XJx40gXO2NenG46L5AMzovR\n29Al0s/wIssYSb234P0FHy9g0/OPF8hxBCshDK+FeHkS5p4UyDHYHg47T8GqsgaK8CjIVgIdANkI\nw+MukKRfYQpkabyEnONPQW5E2MPeiPw48laEPexSG3jN1rZdbQfbjradaWMr+gEM4NMgx0BOImWY\nErTXgrwOchIZxDtAXge5BMfnpR7IsEisPwxyeiHYCchlkAv9uAHIJ/3glk988gRmBb3jOiJ40STe\ncRQkCUYyCnISNpfDICmYHk4RwVvvxQu/BvIjvPArIEf8kwznBt77Q2RgX2q5juz21yI7Ivvw0p+w\nLpB+xt5ceh/kHaRav9a2ow35TziQxHt/D2Qv9QDIVuRVv8BePrll3k72AZPnu692s58LPdd62HXv\n4J3fw5tepdddiIzy/mv9MC89gQOM5AL6tFO4XmtraDKfGszO65vC8kKtSLnOogNRmjZ4o/DPpd7W\nqsqQ1/ILc6PXThxxpt/SZXKHXJUN1Y68Fu/aSOuQw/3sfLDEuq4nfOv5cm9twVOz/NWD0fDSYutA\nqGVJuIwvrIrUWqy1EVdYZ3LaiGXWzXTr9a6Z9Y58c3mRv6mxJdreBH4ZiDoNFZ5AmaEt6Kpp8dYF\nazqXN1U+lh9uIv5SnnS1BduYsB1En3JtSI5o29OWaBOnxF4JCeECV8Q5uW7x39hMTIQyieqMdALh\nBlyoGjPkc+gbH0FgYZNNzdT7Ivn4n8KTehNkKyOJkDExOyNtmM0PEN8JkYtdOuBgf6o2JqoysYKv\nV/1R1Z9U/XnV21XvVmmYOgIT0hcwZH0E8iuQIZAySxXu/yrsuztB1oK46Ghy1HUB0DVuuQ2RHG5N\nUD7wFnxJoyBd8l1OdmFpB5krH7iE+bMT5A6IZi6Tb2YzBpihyAGpn5GReewtO3sVNtbG+FObItt5\n2Y5X4VyU7UhKnLcNjUOwMzAJ0GNkV4DKk/AakTgtaSGFuelEKYomXwaZ2+bFgffRls9B1KxB0kvY\n+iHI34IUuefipDfR2VfR2W3GERO75V5k8JXJd3gOnfQyyA9B3kW82q/K/hmSimuumyKvMGlfRw8H\nuTIc6CojJeQueof6aR7dijFJsL/XoNYfJr8WwmbXaF+GYNUKNvG5DvhAujW6l3VsNpMW2Kuo4VNi\nv85QKBikl1UgFL30Y5A7iF19E7LLXZAtIF641ntBTsIhexiEhsANkJsQaXqRl3gdfPUF8NWDIGcU\nsSv5QuOrAIQ4CM5/BuQGyLFJKA4ssEdBDgPJYe8sjBSQwyDaTsjmRGJoCIhvDiM350KE3pLLzvgE\nzPIlCGcX8LZ3QLTogdFcfPTrIO9QNhfIfQrdgr92q3kXpLYvcu/bA3IKr/ox3vIlkI/wquTh78P7\n3iA5Di+9F6+6BmQU5BO89JrGl9lLp/Y1phpHG2F3x+uuIa8W3nTfLCxXs07NQqQBXs5PBC/XB+LH\nG37E3tBUKOa4oEiIaNi1dogmq3sKP8yF/MguDq01Ehp3N1UW2mpbKioC/ppiX9TfMLvYateXNvrs\nm3aveW7Gc/EZT8yucTTMdLlCZcGY190RKCtvaCv78997gn+m1O2bUVbZ7C41lnst/O66UFuwxFdd\noc23u+rGt/zsheicspYFQV8sVFtU/VRTbUe9xVw7y+eONLgLDxyYKlvdyPG+vyXe94bEzYIsiE+7\nCSSI3RPoju2z9qA7NkHU2oNVI7hAJsMSB3ICu9uBRyO5OnCPDrAFtpUc67jdAdsZtrd37GHbybGe\n21h9uB54akBcPfhjzx4cDfbINnGunzcJ85m8qeFek3iOaVg87G5JlxCEyClmpN9C4ldxPHmrobwm\nA5pOjQBjmfQA2jAMudykCQHcSJ1JiGl2EbInYvq/Vv2dKqP6tUo1IH1GWZdTTW9DKi3lm93F2L2n\nYSthyEQ2l9bg1Y7jxzuE98aX8OvG34RsvIr7VJjDf53zcF8yZpcwZSD6mgAkIMfJILQNbfRkpB8r\nYg/2fRkuoQ4kCjLQp0vSiRK2bRyxCQQj4RIonoIieVlDYvp3hJMCUtlUAzH9YfGUCO2NNX0nLA47\nDeTczbqHccYRy2nLJct1CzsD0W6xAoPH4anzzPTM96z2aIa5mP6ocEa4zEYBzj4qnhEvizdwP4AK\nJHcaDhhgxE+ZR80XzNfoju9YTlrOW67ijvdwxzwE09V62jxxj3oYwFLDvAzB5JPj4LS+DhGjPhsL\nFxHm5JVV+W1Gi8VRYg+XF1c6TNq6Rw/xcWNVWTGvyTcUVhVZ7Yba6bvobyc/xP93ysEchem7nqwY\nmVRQiAn9gjic3CBshuvtNtCP8mG2TCLXjc35TsMSw6BBHJZEA/A5krPEBQBjQAgY7qHKSFdkc6vU\nDKPCv2IY1WBrN7b+AWQudp8EKQHhyL6XT4vCZQ3l0cHoqu/XDengRGCd1a9DLl9GqkN+2wNwwdlQ\nsou0TtgDF+Lo0yC/wp+2g+ipddI/5DAeWmBauk1IHY/momkzSiLvElz8JghHaFNs4CfhgoGOlkaO\noJCRzLDOU2bMN0Ei2P0cWypsQY3OWjt76c3oPtKPYQv9TyB4R2mZhr0RU+0MBJCSR9AZ+WRyO0wW\ncZhSj2hOayAtU4L9aZBjlJODPFRkKZ3ViAOpg4ajhjMGccAUsWqtWsRH+iLW1tCD75t/sDr4zDPB\n1T8wf79daG1oa9hY861v1WxkG9s4gatnMtjnTAZbyH1FvU5qqWMjoM6YmJuRtmHln5iLr5mRbisJ\nR9J2SGI8Ywu8/J3bM9LediazqJkaGGhhr7mHKRmJFuNIgZrMKQicaTEmXOmEKyBthwgwxMiIk52+\nkGtHhyxqJ5CIucaRFezgAB1MLhkaHGJfYfeQ8okC7BMFFCmIiaEjHkhBAWMinpHScdwW5HYcrQJ0\nHkLrY5lEND2iY5M/QAzkNvKauRJjiatEBHAiHNoTbLlLFZU7ywPlbCw7PQG0xRmQhqBntMfiaOGC\neAxHmSr3JLtXzDiyWpDzUmDJuk8E1q7TcDQfLDpahLAXDLD7IKvgDF6NLQO2PsUW8gslHcVdg9zH\n7o9BzoKU4ZgVAdWfQ1DZh6X7ldLXSxEjXmotZQOdsA1PYhknk8wamGT2mVNY3DUIxgqDvKKYlpIn\n7efhpVbbzXYPvNRrEIW2z55CpOkrWP3fBDkJae5zkDUg+xxgg4DP8zrCDtVw8nXHmw5EFOKPZmQf\n7IO40IOtNrh1v4C97h1I7oCQk/oAqtVWG6+Fe35GfAY6BTG/KyE8XAfpAyEVdSZIaTObyWuaX4Zt\n6HVEmphb2V3fh2lhB8h+kPNQ3faDLO9At3S8jiXxNBbTPpDLIFEIk2dAbnYBjaK7rxtiDxOtkwd6\njmBptGGZjPb0YfsLKK5tvbgDSLgPEg7IfkZS5+dfnf/5fCbajGKt7gXZD3JsCZq8DF6TZWghyCiI\ndSU79tkqtpUCWf4MlMtndjyDvn4Gr/4MlvYPMGpWYixcBzkKosf4oOFyFruUsRYFWZ0bHwbs7sLX\n95cyfeoPSr9Z+kYpa5wDKCkzQfJBCEnxMkgUI+Gb2PpTkHzs/ghf+3OQl0HWKvJuSmu32n0YID/K\nDYVuxJK+7HgNX55AFTXAGAmDrKWTMAa6MQZaMQa8IEcwBrq96GFfnw8KCYZCtLYPQyEyoxdD4SKG\nwnmIkOGGHmjr1zAEVoC8jG8P46C0Fls0FKwYCltgjftx+C1Y4z7AYDiIcfAByCoISRtB3uhQhsJZ\nEMKYO92lDIobIL1QtLrx1d8B2QdyB8QCCSrSg0b19vSyp/wMw6AV5Cq+eQ/IPpALIHdAjmIc3FwK\nVo2vb8OIMGMI3MXX/whffAvIRpBdIKufgQAkapiIa5kas6pAmoSmgi9mY3mqvT6yhOYi3kNaXAWp\nme4hBNuWqtT5eY5wfXlwyfMtc762rLl52dfmLNjq77TNe3KgadGWNbNmrdmyqPtbA+FAd391ZY1K\nsM6cEVtc1bG81TPbyO5lqTDWdDTYW/1VbXU2wTt+raAsT5fvmb24LvqVed7WlV/v6Pj6ytZY1D+n\nwRZ9fsvixVuejzY8OTx3zgvzfeVOm/upuS3P9zfVNC42e8qKBH/nAndduD42Pycj/0VORv4lyciV\nEoevGoOicAKWyO2te1qxzAX7sr6B+MRnwizhM87ENfIVUlUjW5tkxCmkDDWwhYUtmg3GhDktJaBy\nUCBnJ8hgUAkuokTDwqnBXIoNkEI2NQ+r1eVkA4TOXAQHQDnpthdg/YfIBmsOzPT1XkR7JY/Vn0XE\n+E3E812ulwFydwkHmbwkQ1MNJHeJB/GzQ7sPyZ47dPuAQrUjfx9yPncU7EPOZ7S4Dzmfu4oPIvdm\nFcIWkH2a3FVyEEkbgH1KRip7EaCdco462akp9yiCriM1vTWImkYmruehXFE+VBySJUZzNtLI5za7\n+d/aG+f4/fOay8ub5/n9cxrt48u6BOOMYMgaebrL4+l6OmINBWcYha6bwLWtaJ7ny/4KTeN/bKu2\nGDxdq1tbV3d5DJZq22KyZasnfsN/lckPIvfThIgMZQgHE4hELeKdvDCc9fFPQGCBoZuwXB4DhaM4\nrZQMquQqbh2MGVsp7PUgd5Q7w13mbiDs9U3owW0CjvcJq4R1wkZhq6BmS69wlHV9zI6+XyWuEzeK\nW0V8AEUgz2eyEa9VR/nATOFvS7+sN6H9T0z8hvsBG2Mi15hQBRC5mG0tk1ynNFMZQgpAHYHyuJ9o\nbxc+e/AF7pM/8RxfLGS4AJ+XmBFIDs3YMEMgZKAZlOKXh42RCjZmS+hQgMm12wK7A4cCxwNMrrUF\nKjDQOpswbg0BIFtxBk8WzmUwi/+bJ1DQdoANTBtHcorHOFJDokhMr+ftvJ+P8iq2EBMkFfpHj2Rt\nvxAV2NF1kDa/aMBRQ4Ojoa5hZgOg5/SN9kZ/Y7QR1zViZUI4RUyv5a28j4/wOEUjWASvEMZNSIMj\nFJh1MAncpdvpG+wN/oYou510r5EO5O5pag63yoZMMw1P0trNlaKZBioOMkYHnOX86khJpc8caysx\n6wVzRaVeX1lhFvTmkraY2VdZEqnmO2a2Su5gRUF7ka2y8C9qmioKeIEvqGiq+YvCSltRe0FF0C21\nziQf/W8nnuPu0bdwsHGVHBTXK+FebHzG9Ju57RyAAFQUsWPIwBNawkRPK1eCTq0gf0UNQZ3NSE/7\nJgEPQewE2DcJ8LLHUP4u7ANy0z6I9PlD3SjVCNmgniT6EwlsOLAWfblmsi+1DdYGX0OEPo260dzo\naWzFp7mDTzPtI9/DnXSCDXfy404zQQjWZ60fd1I3mBs8Da34Krg13YLdv9Ha6GuM4NNUa8xynKgM\ncU32ldZGsVWOJG1V3HChe//upxH+o5+GzZM57Nt8xL6NlvNBXweuXBoquqB+wAGwRQU0FupZRP+i\nL03uYjZQikMfDQ399KfCvgefhcVX5XtVsXu9S/fyJzQBKYboPF5NKRhaWCc4ultg2t2sbNq2sn9V\nuNsaMT/8YAuNmatCjM8j3JgzEqdBLBN3HJgjJzRpGELkWwLcMMN9iw0qG7RQYBRldc8UfgJaMTuk\nUB+EqRUGpyGAaC8tQBFpmqb4Uf4Cf41nc34/RkjefuGwcEq4KHzCOFhMf0R1WnVJdV2lQoi6+oj6\ntPqS+rpaDd2PzgaLky0N08+WDqrIaJG9AAcYm+Vlf0IIRoNwhM9TPdHR8YRqhnam1ztTK7zX2d3d\niYpoFEc9yQe1XE9CBzQmREFOaGSFSksgKxrg5EwJnlO4oobtaGTcP6wA7DR1Rv5wIuvqH7TjP/bi\njeO1479i362PG+F/LpjYul4gGTixnpOK1GI9u2CayNMo9JUHYx5PLFiu/PK/P3WP/XJZ/PTf8n/P\n/xNXJXRLVUB/XW9nSrVdDrFZDzt/Ech2GbIyUZxOrXdvcm9zM8H5Fgydg25Em2BrCcimHEBlJXuv\nSkVgKGU7pWRtryyVOXPKxQW5GKB9Kml0AZ2wgDEDY2mlDGCQBFSoHCRwDMrzv4H8GmQ9wjAITe8Y\nyM0cgOBNzOuwugfpo/thJNmHKY3YMKkVSmYPyD6QA1ASjuW8IF8gveFD46eIaF4PNeFdRDRfKL4G\n6aK3eAUCm9+FBW0popuvYes6ZJljIF+AGBB8MB/e/LPWD6zsNn0Q8+/Dkn+s7Cws+QYI+kdhIL4M\nch/EgMDv+SCE50+uuXdh5V+BPv8AW0Xo3/XoVUqJly4p2Soyig6GqnQAr0ngDfvwNgThj4wNKY53\n6StGwmDxTYhI+RCRKLxzJd7kJoSlG5b7EM7oXQ5DJblLuiladTiXSnYXiVInXedztQeeQgtPooVX\nQdTYvVglYwx6ZWEqwiaOVaPRamSB3GqxWPn/Xjzbx4Qnm40JU77ZxWH3ymD0mTnV1XOeiQZXuvk1\njhq+vLm7tra7uZyvcfj9Pp5nolVrKxOxeN7nl+PIPhJa+AKyyW6SOJ6N2U0E2garCllnpVu0gA8K\n64VNwjZBNZADcVLxXM5OK40BnUbfrxnSbNBs1qjI3nYLEta3mNxiI0EMF04gRKVIdGId3IDgOhVP\nYY3qNKapj8l/oT39X+166qkuoWX7iy/K2Ow0p7r4L2Rs9hPQ2LYzAvGlIy1pazpkbE8Fpn0KQjsy\npyoyWZx26U9hGHgLcuzRyjOVAgG0tzIhvtKY6GKthQd5cJ4y5Qh/XZlyXWyn6yH89a4s/nqXjL+e\nDDbEmP4ImIUgm4FdxpGZbAbO7iIY9tlsBs5eMptmYBLpOuz1oZ0mz1RfRjbjEfiMzzKSOuI77buE\nIhPIS05+2PApu2fyQOORHMb3LwD6HW7ugXViPzLDW6F39uTMEfvg5OwFOdKOMQ1yE+QXtDUb8xvk\nr0GuQkm92AFxi5Txk1MMMkcxFM+CTG0p4fOfAklRWhHIKZCPJ7HJ0czraObBxqONsLo0x9HaA1Cg\nD4SUhvagjfvJ742WXQXZBzIK8gmadxnN+5QR638EGRxzQvvojHE/+J2w4JFKR2NuvoQfnU26x+OB\nL1AZTFPmkf/ReUaYij7un9kMc3KdkraQaYy/Y1QCTsmZmcLm5WGWKMrAzF3Mlq//58uH1v/Ot+vw\nP775S2mdXTxxhP8XoZyr5PyCSVIVAU+Z8bqUHC/KBiBQO6UTIPoilQx8nUzrx4BWFtTH8LNdv4f9\nJHQkOumNCX86UUp2Yyuh2znSqPJRo3ogv5yVvZzV8FDYL4lEMjDciayZWpchGHJsMrXaCqBlUEsG\ntCwjnQPIs9U4UsmudNLj/GSmpqULgdvJ08IlqL6yGpb8QLwJbrMSgIr6I/mn8y/lX8+HB4V8kojE\n14OpXyq5ztTcJNAm2c8R02mUC7mHaDM9LKB3YYUs0DqsDp8j4uh1rHBohqVdWJI+LPu0DFeUn0ae\n80Ew+BvllEQF5RPuHWEgtUNA6hBCPrJJ2my9QNc+gLiUl68qV81QtasWAgcUGZPSDeBtH8s/m/8B\nILiPUlMJKIM1NXWy5HzJVSBiUijOSbRRjTamsHUX5O9hEvstNVl0mBxuR8gx1/EUmoz6JMlLZdex\niv4Ya9MBNHhyKT0LAi+zJyxPH7MbsjjJ5CGzPMN8WtlLauX7a9qKwq6lDcGmxeGKivDipmDDUle4\nqK0m6ArVmEw1IVeT4Lb5vbXC7E61f87SYHDpHL+6c7ZQ6/Xb3IKgcQU73O6OoEvz0Fr0HUmDWNhN\nkPo0kOUIZ48tMNwQt4HbDJWJqfe38Mk3o78ENcV0q8nfc4tk0EHVetUm1TbV5IolC8y0BkGIFCEd\nJovUTog4E7jLBrhHBFEtR4S7fVp3JMQXYDX6ar/Q8uKL29m8WTbxBfc3/GXC6fkWSehSP1ZMeCaS\nHGfkhOFYnqzXIVdGPZCSA28h42lkV0U+CbAlaekW2O16+yaw2wS2Y/Z+u5KrQxYjw8OhtPpMwmxk\nzCHYFCmV7XDgDcVTtv+m0marnPovaK6qMrN//FeyG1n95xvceW6QydmLCO43IwMr3wOmso638bW8\nOJys5dt4Nnrl2GJRTkwWmIiJuBAFCpejSOMMYbWxi62sz747d+4T3/+UUnw4+8RvRK2MHcctEH8i\nVZaK9alNpdtKd8Ne7CxlU+9c6RX4FJaUDiKLe0yG18Y3nyBvD0y5Y1i6E5Vy4RSm1hC8ZSmyqJND\nwQ1BBHcE2Z1OBNPYjrHtxMyM1I8qFRtmbp7JuFRtOjHTmJjFLoXzm5tlnCUMJ4LkYSLn0ixjYkFa\nGkLQVBBBU0sWDS5C5uCiQ4sQ1rdIkQumla1Sgngh7WAEpTCaAmoRQj/7SOTeS3FFxiJXETvmNibq\nmYgCK91EPVWESLRmkmOttxH3OKuVQvdmBRKtTKxhl3bg0g5jh6tDRMkt+Jcm4nhE3BkPxMVhaUF9\nK65YAE/yJIO5AMtIL8jnkLUARAsdn22ndohIV8Q5uTJVADOT4kDF26VF0iL742X4Gr+ARunQ1jGN\nMotZn0LZiKOIc6HCEV8g9MWgc+jqdKwpUbCrXfkH84+CXV1G3Md8pbRQalfBwYKjwE+8DA72BQ4Z\nChwFdQXsQhXE58+hIJiLPUwzSO0o3lecKhazeeAREDWk6zBcZjtK9pWkwPgugPH1gqzMJUYuB+ci\nvAaC8V4OyeUayA0C44GJ/3TDJZj4VzLZJHWp8XrjPYSKUIzMq5BNVoFcBjkLchNkJeSVLSFcHLoU\nwpKAAxtBboCsQCjja5BnXmtD8kBY6IGbWoXOJdD9HiUCW4qgTyO6Xphe2wriiMYmHEBdDuaIcP90\neN2Z2CKMvxUE5UdlnvAKZxou4xUowHpVLsTnPgiJhyvQ6FcYSZ5qvgip63shxCiF1oReDsF5hDbf\nwetcDH2C11mWa//rrP2mh+ArtA8pwp6pCOdsAXBPB0Ff1rT8a11dX1vepPy2t6/Zsmjh1jXsd+vC\nRVvWtAtzip/vDj0501UZfTJUE2uuVrPR1eJt91us9e2elh4dPzT368vY9S/Nm/uNZcGmZS919299\nLhp99vUl2V99fKl79lNNTUvbq03eqLeurayxo8bd2VQxq57kmkpunVAoPM34TYTvl6xAUUNVMmkI\nJOaXgdAYH0sCw4J1QBqdnAAZAolZZenCoH7ASa5m5CWyDwBMMITkJpohITVvbt7ezJTtZjLOQ6SP\nlPaCg8muz2TE3IufsL0HjH2f4taSredZcTrq7oPtvM0bBzgBwIoUJ9Vb5K+sj8OifxS84gA0gbZA\nPACZJnAUNXxScFNEWnvhplAeHjb3wO96GO61I3hcFkblrcpjylOlg3h0mzs+5dGkehzAMyP1vXjm\nfjwuEujFc/ZNPkc63Pro+PBYLFqLBm5+2cJDYEgRbxgufzlUNGL9vfLmLq+nq6m8vKnL4+1iMvIr\njnKeL3e0zmitWlRbu6iKbTxyhP99X3eosjLU7cv+DlctqquTzy0rk8+cto9vXzvxmVCW9dPEpdKq\nST9NqXHELPtp2OrZkJaCOT8NXDTS8aDiCyAHzDTXzDSnjeKnyeFGPs5PE9Mfs5y1fGC5ibAa2UUT\n079Tf7L+fP3VehXpgD8S9kI2/ZG4F26ZsNhDThrGggWlPk8S7BSnFO+F4SRc3IOfH5XshTMGaDmS\nvpLPYuUMJ486zyAUW4+MdiBjJY+6zwCyTA+LRxQkDkyco4ikuw+ix24UBHE/kt4DpHhwaoUrzcQj\nTjv5gchD35x3t7qnewatoeLQBnh0oAFBE4JHh//5f8yjM35r8cMOHf4PmXzin/iOIFLtgyffFtUa\nVT3Z9NJZN85tgc/aQsn4SQZB2cw6NcNQ4vJUsoWMrGIa0hb00BZgyAWSQ6g1xEf+7u+62P/5e+1f\njgoz2/9OtuU1T3yH/4Iw8f8ze37h456vlquQEPyOgShb8lG4BhJeIex7HAyYOSgWapFJN9kiSaUj\nHBZVYEQr0OhUUdUaEUjsaGux0lb2jwniZDCW2/wu+6+LiKBqH0+1nzjRzs9vPyFjUYT4ffyAkCaZ\nKyWVVkJGZYJWVqpaIqcyQYwifMnJoo05SF51BsKKPZPFBiJ5k6ewnyTsvuAMWNZGQQgelyBOTiLx\nMwsPdxRj6CBWsTOA5coqY3IxkgO47DQICuAkDxecwhWHccVeKjNYwv+7oLN8g7HMYzZ7yozKb9BS\nC1iJWovyK8ya+mf8Tv0r+0VfTVwVlvJ5wjGS5weA/g+7cSZmkg1ZMoo+bO9jGj0TGzVGDeuOfETx\nJBHAw4R901DJhpLNJdtL9pQkSk6UpEvGSvRQNcwBG5R4kVgOBp2pJVtaF5xyyvbecqu1HP9OKBvC\n66VOZ+mUf0yOXsytEBYKWmpnGbdZ1jygFCWhEwmK7pGE2sH24FtinXoF1kzYzuWiD5se0kCwbSM7\nuZ0p4ECUGQLhMPe3V0CJtTsYE7UTkgpTPRwEV4bR4Pkd2oe1qrWK/6OHVZAz4wI//gNFDwlkN863\ns/eqn/gL/r5o4xq4MDdH+LZUDr1vDKhB6fIxaNQxiHSbQYZA3GoCOHEHpH7G5xgvT8xJY+aw8Vqd\nSTSmYXxgU6g8G3w5YlITkIIvnfAFRmrZDuPYIRVFY7Yrpolp+PqEDwzz+pwCBMqjhOLEnKzH7jh3\njrvC3YL6WUBzvgDw9KAmUBSqTcwhvKw6K1PUB63rrZusItMirIeYrJE1Zyf7rKusbBRVUYuryMXH\naG0mubl2e61A1awa2Y0ayO4RxmPD58JXwrfC7LEWYyICppCS3criQGqddqN2KwT3F3I1UrWI3dHA\nXr0flcJSxaPFFyBTixAtyWhAZve7sFifNX1gYm36uemvYPDYSYFekFgoGhuxV9LH0L1+BPI5bKcv\nV74GseJl52tYcQhw8TmAKb1WtwNgSheALPQKDhyuO4UDVyHDrGwCE0CbEX6EqU8JRRo0dC+s69Ra\nqt5Kgj8xg9+ikQRPdxVEi9ZTCdLLILty9Vr3o6n7qYoPWvkqIuZQ+lQ6yZqRerkOLYO1BC2j5q0F\noaKWK5AM+A5SakYZMU1aOrCsab1ebXGlKPuK3a1ery9SKYYiWAvDXp+YNYKMV3dH3FXhbk+wpm2G\nu7DNHK/xxGfWOCPz64M96yvbjbW1PmPQ1Ogr4xdEg2UzXCWmqhl2Pm5wNnY11vc0V4g98wptTmPQ\nXcWPf15Q1dTdVNfdXCnO61J11tebXZY8Pr+yyROaW8KvEMzVDQ6Ht8KipzWqW/gK93NaI5slDcf0\n6t0cvIVsUMjcS1Q4VkrmYCL4kp7xJTEznR115zjPf1M4Du6/gtFd/PtslvYwJT+JSFxheERUP5A2\nw3gVU6Jok0PqDTCijKmnQVooYpSS7S1X8dnV1cVuSesU4nEe8GOcjvPwp6QaB2Y+hJMTIBwTTmCh\nRwWhfqTPOGQAf32aoLbZn+QZLg2ycQHwbyrB1Q+yHgbpbSBjICdyZbmcrCVOw8MynJOcZkx4Mstm\nTuk24nM5PT9MMZtm40gh+3Ox2Yk/Fwek7cVyYhyVTqGQ2v1grqug5Mmw3yCEDt8Dsh+Low9bvYBD\nIOjF1cD9WWl8wcim0hbjTjjLVmIKbMRkiFiRGGs9DWYRsfUC4Odo+ZlyWBkrTgMtMQoGTcot3EQS\nByzDJVTW9wChjuH5kVxLsDgnw/k9+ew+1nwf+5Hxdz9BQ1ZgCu4g5DWq8WiEmXSFca3xFePrRlW2\nLUetZ6ArUZoG+bEAfygdBtGiKRGgN16oulYFtHhZJdSyqSJb4KcFkZn5ZH/c1d5QJojlje3u1kWl\nobrnZ7asinlqYsubW5dGK/nCuU/Z68IVYXdHg6PJVdfaqMiG3s5lwUol1+EB5Xmty+bK/oSNJx8+\n/rC0HiNgCUgAuzQqOAQBbvBu9gq52ooP3+NpukclXZ4MeDu9rJe2g0+M1aFfb/uzWEXydcdy1z1H\n17XRc2L6Q97j3nPeK17WcRtywzEInRwYZuzvbcfbzrVdaUMIedu0PN6pbdlE93RI27M663ByzH/b\njzXeb/QTcoDIhdk1d7Iy3iL+r6XYfDZ79qDUahEyWjZjawgkxghihaEGzTdS1bAYFpFEJDBSSsew\n0jQEpD0N/MBIJZtt7fNjlDIGP8wiefvsImUKTcPR7mY73Vgr3c3d8qpM2lA3IWhDP7bzD6RaNaVd\ntbuzdlVJi1D5FflrgSsMmOzkioK1kACBAp1cWfwCnKuwyUtnYRhaWfICVB6IkdILYOjrAhsDWwNY\n8KC/rW1hh9a0vtz6Wis7tBYpTadms8vOd1xFYsqKjrUIzD0FT9L5yfK0yfNdV7vY8ZcRh3keEeYf\nIOZ2Y5yd8UH8ZpydsXLBC6jI/AGSe1cufGEh2gDD4AcLby5EdCBhg+gx50/m8P2AhyydgplrBRYw\nWOvlNNIVIGuU9kqj8G6Nok0nFz4aNCc+tK+Vl6VctpFS9p3mVTjC/6XFF612t/ksFl+buzrqszhM\n1Y1lZY3VJuX3A6uv3OgKx2tr42GXsdxnbY97Zj/R0PDEbE+8/ZSzFZe2OrO//LqyxiqTqQqX0u+3\ndc665rK67qDDEeyuK2uuc+oE43M9jfNby8tb5zf2PGdk43F44gvxFW4Nyadu7qdwa5VAkobcZFXM\n9pN28THuNpenCK0AUMjHaflD+RvyN+dvz9+Tn8g/kZ/OH8u/nY/T8o2Ma0FpseE025Btg22zbbtt\njy1hO2FL28Zst204zWZkvFIazNV6KGPjswwsvigNQbwMCZgJc5rE8akSrPp3bIuvKBLs+NuPbimG\n9Yf/cTK+1TnxOl/MesaJ+CKmmaqN2bJPfJqTBLjaxwSwAA8TmcXrD2zi9XNdnHIt/xldW04XBqZc\nyAvTLuQ/G8/nP6MLBaYjjAoL+Z0UO9MC1VNAFCT0VIEQoXg5bEarhBeSFisDJN6mcnC8uarVw/4J\nCyGws39Ce/uO9vbsWi1Ui3mcn5utegKJCeoisT65ybmNSYFsBU34MxLn9FOUKpSS+dxq4Nu8hu23\nuXehi3ydEKaK1FQYCba2X4P8HORDEJd8+acweD6NsIgPsFXhojwc4Acn91WkKuSnudPQABAvkwRG\nKbu7Tz6PfNGvMQLfY50s57cwnrYEKWwBkEFIe50gm0A4ZAKOdWLE1AQACuAMTEbZKKJCrj6irxZC\ngPQynvIeyB+BVDhrcTSD9fAmGvpWxTEs05yPoikJnsxaipA96T16U/n4dbzfJibrIJQSJqqoHLL3\nPM6PIDBnK9Tlb0Pt7hGXQ3TeAZMyme+1YD+ElbEV5CbIUkhlpJQTasZbIK061kejuguAPqMkzR6q\nN4stNTKQWkEAW5SM5vXlAUcdjEyPgjbR/D7ICmdy3sczYGo5l6mMkEx8mVI79ZDP78D8eAfhLyhL\nkvym7Q0gR6+0s9tttG+FPfQgpPU/gIFyl+Mgwvmp/iZCfJJtFfEK9sCVkOJ3onPeAtkFEecuAqK0\nMGT5yJoFkoSY+DxVDgXpqUF9AW8PrJphLP1hiEURfKBaFB5ZhQzSd7GkvjljMt7/TcoAgRqwC+St\nJvREc18zLHDNB/HTFo4j0v8AIv13gRwFOQCb+S4KZEBeZQRepTdn7Z/FLnizfX87Voi1GPyvCltg\n+CBHC8GSrwShD0c1uI7hSxyjNGF0MWlnyxEAdZWcGkBrfBVgC6/at9izPSnFEQ91Jle7NF422Xe7\nsiWAWetdBxFgdAC992MQB/rs39CP9dhaANIO8gxIIUgvDIJhyCzUgb205QNyv68Xtuk69OPT6MfT\n6Mc+JppIBpB9CPzYj67cj15shcSzn+I90FfRXK/Nz3XdAfRaFOQAkzP4SlE7zcJjsUYaRdmeDAha\nKxNDH7ZDDjXGmx28LToUD8smxvCMnhqh1OP1W/+w5kVHwNLuCFrX1I6P2BvmUJA5BZ3PabALP2z8\nyrMvzmr4yuImRbQsrxQ80WBdabSmzVZb5DH7za3ucddDpkriseT/JZ2riPvm2/mqAlU99H+q3xfT\nK0BLquH/yLqXvFJ8C8KOEwEI64s3Ybs/BwtYxJhO0SNYSvoMWyqne399TKvKeX1L4nFlXfpPgorL\ntrmc+xv+GrX5/3u7QJXP2pxvlPPTkku4QSzBGjRX86jV67YmDwB2TI10aYKamKZfo/l32j1N96OX\n0MkRmdmmT1U8EQW7bErT+YTS9i8fZGuTMtIrcpydO/E2r1ap6pNAwEImKNzVHEDbTmSD1WDbJFc8\n2CAHwDa56CxFsWD9VGdAtXJZ8HSikH2w/sKhwg2FmwtVdAdbWupEaGGwbBpYneICoELOhoci8FHE\nmUdgbxqpvVpC5C+RGXlcQd/npOV6VGDK2pxlS5k26zwzh/jq9V3PPru8t7CiMD/fUVBWXaJZz+8c\nf4Hf2b55YIlKbBdVJVUz7K/Cn47++CXrD3xLP58HDKrb4BQcCjoUZlAAcVgpdw8Mv4dGn459TCMn\nx4tidGqGASdepH4ApxfMY8WPxNxUZpInKtPwIQXhgK+ltd6F8iXkykYZJipyJCXqp8ldSq/Vsp1a\npddK2E4Jeq0M4yF1Tg+wNHEgltepX6If1K/Xb9KrEbABkbAgjYcVgo4UY4WkfSvkOKDdwI8St69E\nwITUaweW7RTBjU0J7e/s7l9WlpRU4l9RV9eeR7te2GIuKzOzf18+y7/f/rjPQHGJn/E3GR/w8F+X\nDCViPRpck2YyxAjPpI6arIiCmoTSEIJmgYQHTDyghVEFM4NxpIx+shXEEzmplbJK86dOIHSYx0gA\nz2pPEUW6BCRBTYWEPoKMYCKxSqkgDtkHpkhknLNL3HQiaw3G5HksOstz1nsqBnkY5B3Y4gFmwT70\nKIHgYFFCSZjkaP6FXA2YNSCjBMUFQeBrMMWdx6L/CQiViZ8JcgDLvB6r1UEsSVGs6fNBrhOQ7ztw\nhi/XrkGKM61+W3G3V1Ft4qL5Ezgy1VkgjAFpL26lwa3ewq1QA4av0mZBaB6BKafAOFMV/8vxf1RZ\ng7bmJ2dV1cRWhOa+WNFbGg9Uz6y3OxpjXu+Cai2/TvjOeb2uevZTTaFls6tjHc66JnvdzCpPR4PN\nXMKvJ96J+fa3ImZeBfceqiPfRt9wOsIGlYJUml5NBZLV7EeVAVqsPiPX7wQtYSfBzgrPgEAge+Vp\naQNMlNtAEiDAoJbSTuX7E2cpnPr9H5s4lgt259OKG1JHhu88CryzZHmQgjvCJXsLVjA1uwrR8L9z\navzt42fEZ+M/+x3zgJt4SdAIaa6O/w4bfkifyAIl2DLSEL4ex74jOAvTXGppjJLnqdRky+4wdcyM\nOgS0zzioMyON5TrFT9dwCT/yJ+itK9hbV2By+GW2qyXrHJg3Yw9+Yg8VxhE3vXwqwvfyK3hxCoht\n8hXhdXherYJPEIZTO40HjEeM4oBky+U/67F1D5YHXbENweorEVt3D4KWDkJqraPNgRojbDt1pOx0\n2aUydvlBAmcBISCotSBvgkRQGGqFB+Ch3hVeYZhL7TDuM6bwSAsedBeP1LKtpKbYgqdR3SSKNtQr\n0YaqYekd3HoU5BrIfpCLBAyEh6wDAfgW7xbhms1Nh4iJfeQIEvCUb6zVhvj9r8xVl7ojtZb6Ylde\neYG10pQndr74SpmmtKbF21JfXVBRZHeVGkTLi/xXx/eUhWeU5RUENRpTpdfEPxne7myb4agI6vS2\nmlrjt2mOeBnREI5cIfc/UVViCfhcfkbajZm9HqQTJXsxOBi/E5HYNKJV0ZpJ6ieOMm5fEJDEAiXQ\n6vF1ebWFMlBpIAuHIPmziJIDKF+MW8txo6KCXnAeX/4aSA8Sk1ZQJVHYYslW0wZih92pr2BVgTDM\nOnCWQL7WqlY+xK8UPrsTX7MmPv6/+cpnhG+N/2HXgQNP8mcRq7hqYoxfInzM3llPpZpFxl3dvJXf\nz78bGu8QPnZ+WZa1cRsFKz/Gmbh2ISK1eFHVzyujIcGyvaSFbbcYR8rl6AQ2e5vT7G+J9nSinSm4\nUFivwE7UCXIcBGAs3CRgnMINyC5neMiHRTtRthPVyTUuwSTq5ViF0igCzpInS88j6i4FR8rHyPDf\nXrqHHUhEjSNWdlZFVb2i2ib/quIX0Go/BRMO1sM5lkoG3wu+HxQppgEhaOzPrRT1BELK6n5Eoe3U\nHgCj34klZmf+AcQ17Cw4AJtfK4b7PpBekDcx7xDmJWTju17DqkIwAmuxFceiEMdS0EaaDxShI1D+\nzoCchmYC6DUpDqUkCpJCsvaK8FqocKewfT5yNcKefzhyiv2kzrRfbr/RLiKMRkbwf1PcD0WbdLMd\nVBoZwzdO7myQH4N8A215H+R5kKsgrWgkmpsEwApeDS3sATmNxh0DSaFxp0BWQBO6BE3oDMgxkKNQ\nhy7B7HoG5AbIsfbJEAyfUlUou9hNQ6WkQIzWXOH7V8sCnZ6aOc1lvK2xy+/pDJTlVwxEm3vqTYLr\nmVBoVZe3pnNFizkQaCwVukyR31/S84cNtz1zmiocAXY6+61omjP+A1+gonmud2mwtqZzZSi0ssuj\nK3WXLR4PepfHg41Bjmo1fCZUsPWxhb8olcKodUiWxgmPEbGc0olsQGd+Gu71Usac2bj3cjAKJ7wB\nqdBbStZmQKdXyEcrAih0PwP1G1o3I/ZoSVgZ8xQ4XviQY2laCWHJp7XLIIgjXjaAi3yE5WWXwXe0\nlLaK0bpOtRGqwavwl6wDATZ48k3DfpTEewmLJvlDoiDkl+yGsiOnMUlhmD96cobdHghB78PoQZYP\nDdT3s9haicoA66o2It8DqRTJldUvVCvBWN8EOQuyEjUI5oNshAp9LYh6VU3Xmu4AJdUCzNQLzdea\n7zSjelWzpZmtIsm1qlfQ/OfR8lcoPQu6xsYCpcko7SWX8R1G4UTWfII0RKNGs0lRA8lk9XtozUto\nwxqqrIf4sO66ZXVCtilvMBJyF+esz5Qzmx1hrRY5FcHrbpXL4pEMsaPL3PREe21PqPIbM+bUlVZ3\nrmgtrCzMt+X3D744UBn2WeOh2nBVoeCa8USHx9bQVfdSnaCqifb6Wld0VInqqCg8s/Tppe0FFYHq\n9q7KxjYH47V3hBbuHVpfngOiCjDZHwd6LGZieZOIpOoBqUjkh2MFQTEm9otD4gZxs6hhmoZLVI6o\nhxOCkkbJZ+REccbKxJDVbXj6uVnCe9tlHXQxVycsZG3QcN+eNJ6qRQD6xIr+i/pP1T9X/5X6F+oP\n1Z+qtewBZrVH3aruVi9Tq4elz9Q5QH4ByQ2yBVdWV7MlalQZaQIqq5oXJhOqZINs8hR3EeEcp8VL\njCuZ1GZ1q8ezmEyz/2P8KaHlN42/aT9zButMC+fk9/J/w6m5PH7R2xqVXlX/NqcSmb5MCv5Acok4\nmC2IkA1WhtyoZ9JihuCcmeZKyO2cpDOgZh2shLfA/4AuD0FWSKeMBpchaBCHUycMacMYyh4YUO0e\nkpZc4ZwN1+XQyO9T0rGcI9yHLGEDHaVMMjkRvA9Z3AYsxvcpWt+u8quiqj4VjiI74r6ajqr96qi6\nT42jajYN/Jqopg+h9Mvhd7lPle3tWr82qu3T4hw6SqXs7Tq/Lqrr0+EoXuU+gWnZDX5D1NBnwFHA\nEK4EhDUwc9if8vx5sIDiTwTT/jQcu0+zTY9V64tY1UT55q8Hvv/9wPhF+rmdqPrlL6sSRPENZrNv\n8JfZb9D6tl6lYd9AVHGqemkIdok9RLAoDskV66FBwIwBaCYq3uYEHLwTFtnjcHHrKcDtNgLc8tIc\nexGxPnVCl9aN6cSBlFHn0gV14rD8bWT8foK0BiJ77sNIdyhfV8NbeC8f5nt4NiRXKmUdpqXU36Hv\noFFZVF5VGN/hjpquVFvUXjUSQdmVMCuzQ1qL1qsNa3u0uBn6/A71OYqme3Vh9Pkd6m6NwWLwGsLo\n7jt5dGWeJc+bF87ryUOdytVoxzLqZtxkGetrBI5qfR6iCepj3v+YrgZ2Mefk7lBf/+XbaqXeU3Ym\nAWl8UIuxzIsYy3gO5YrsRnaDzB7QgyJYgUiQcPcpvcTOyeMYg4DLjuOUPIxFZRAjkt4u+sWoiEO5\nAgGPHcYpefgy8UIuq7KaHYtgHGnv4KW+HqOXkmM52Njh6H0OvS1QvZiJbC2ULOwV+55ylor8ZiKP\nwUDcD6/Cu/gg2rgbw6sTrbolylEKd+jNLExID3M9eDPCYFfTGMDryQODXarGVXfwehbRK4bxemq8\nmTww5GHRw96MTQ3cAZUupOXsBAB9+SLd9EL8HvmNeC7OXuqy8Bln445I+TbIBUwZhK0MQFxsvG6S\ngdwAzyWloeAjAUaacEwD5SicKv4rwi0lkmGhF3RWSA4k3JOY/y7I25hbBdC9YTRCDyzHhDpFxecw\nSbYU4X02GrcadxkPGlVM9DusPwXEf/xB2gjwrF1FB4sYu82Cl1jMTFvOLm9md7xLyKuuC1hXL+8K\n96kbQ7VdTDv+kcllLRhcOX6RFxc/pauJx24jtjAptPDttG5puZ8CGWCTUqExCex9xo2FTHJMuC0D\nbudAtqcib/8/ALfl9PaUXCeErsrWDWFXqTJydOyjNT/YcqfCckcORQ1b9DROakhaxutWs39HZj33\n9Pjbs54HcPf27exberlzvI/8kW74I3nCQlRnsl7MTsysTnT9FLekb3yC589la6OxscAdEI6QzXIX\nU+ySscL+QuHfMVMWTzVT4u86xVQpbUaK+VDxBohiu5VaOlKsGEKiPjBpNlFGjFJTJwljo5At7UBV\nHdZn2SwFRD1kPzwwxUo4zSRIMRuz2Dt9QTEbL7CRruHmUMTGblRWQwqlINdwSMbU/Wq51sPExMRH\n7MyCKdc8za4pTR5SHcfp/SqsOrfVcpzJxFV2Rh7FmcjnPsfObYkV7Vbh9HOqK6pbqgmVdiBZpHKq\nhGH2B8shy3HLOcsVyy3LhAV/sDgteDK71x127TtTnruJ7ZekOK1R69KKrI3afm22HoUw8U8Txuy3\ncnJ/kbCwb2Xpt0z9VnmT30U9/Lgvl7DQJJc2u/CVqjZA+N0NmTOGvPaxKszw7FealhNKlh2mp9KX\nUT7V+mzNvuxXgm3HKAvwPWXLy4QBLhUvW1n2Qpk4MO3zKbWai7P6kC/3Mf+XqDPpbBWFqi7BGmkp\nt+W+7IMUL6hKKqqLBe+X5wxNzV4D8WXwsY8YHzPwf87YUPKQ7rhOGBjRqqmuH1u/RbDBFkyBHhCC\nFLDRwgbyR9h9F+RrWOeZ2FjCZJ6UWwgJcwXGYJdBAgpj7swD+SlqygHpcruACZ0QTghpYQxJ9zoS\n294C/8cikPxAfRMRd3+MA7+vppov0tcgRH5BGaWiyqRyq0KqucgoHSIg1IdLv0gih+D4JArYCXJi\nanKt+Aq2qXLyXqwkP8RRVPlRshLJE66wZeLRyudTKuY9VNaHh2E6eZH7BCEAq7FwWECACM36joIB\n1uJJlBi7EYRKRB/Bg7O6OJV0NoNo5Auu51ArCa3BA6mpVINiIaZISKt2+xAx/8Y/PHuDF9b8tquL\n5//+wvidO+wjKjGNhC8SZ+2XtiFJF1VVBLLjUkxjEmWXhN8V1fiw8pmLapTvP6krfItgZMArJZ7K\n3MT0dfxMfj6/GhLxv+HBwNHB5P0u/0P+Z3ySf49/n/8Y2oxAPipoC2oV0xaoElwO/5KfUkhOQYli\nqoKsIyRPaS4yhs6r1WZPq0dYOP4U0xQEfpy/d+ZMO1MX5DZ+h+JE1FwDJvWUYBBFNdBmuCynl8vV\n3SZhwgOzWJWwsH28gx//zgft2dpb3E326nnceXavJByEcoxoLlkii1lDKRrSZlhTYrC67YauOoaU\ngaGCDQUYX3xASZeYNsqUOnWxoun1b5iqpYfUg2OsQ1EAK4mKWEjAPa47p7uiu6Wb0KkHUkU6lMti\nassm3TbdbiY7ZwvSsMFJGfi8XBRXowXucLY8VK4wlCli1rLlX9saYR/5iSe62P/5s0v7nhr/z/zs\np/qe5NezPpjLcaLAj3Ez+PcTMwLS8Rn8wEi9msybMxByRFUBpW0gt0FcjBGOuFDJlyK/LewEKObb\nQG6DuCzsBDMbjojJkzYgsa+zkfXZOWwNgmwDKcKxTmy5sDXWqAxUPesyvTIxi9lOsWFqZyo7SsUJ\nSa2XbYHq8xjwaojk/wTOUlhM1j91IZsU7xd+XIjg9DQqNRcbRxzCA8aTRzyyjEXpHCl83Esw5MRz\niJKXc4iScdglKL6BylceRFTDLvtBRDXEYcq+BBIFiSPEVFc+WT38OkyOB5HXtKvmYA0iWWohA49O\nZlRK5/HYHghvF4quAfmUguDDeGYvyBt45k7ImK1ZuNAB6QLIVTzsAuGqg2iB1XINz/svCJXYWcMP\nmFq8qGcqO5yyYAxTJcIpsqEo9Aq2ZXWm+lp3fumKAJMRm+d5mp2F7EdT3+jp4l90tDh6/XU6s7ey\noYUExuLehRXB2VX3sZGVHGFf/hdhJTch/FfGp4yEy5Itr0KCCpuEE+P/yhcKK8OyfYIvZvN5EbKt\np8tnFCwGDZN9Ipq5xAmK27GuTZTz/8hkmXLuH6R8DvI5R7khAK7KCed55BCWLpbIDnZHWkqjZxIg\nVBZpe+U0ed0w1VGumTr+lB3yDOtkr7la9tvkpaUSG029DAYHcHQkh40Y/bdhPf2vIH/moKrTjr9y\n/MLxoeNTB1WlTh7VndFRFWX7Eftp+yX7dbsahcHesh+zn7V/YL/JdpkQn4W3hG3UYs1mr/kgyEfi\nlS1eSxc+Gon03f4u/v3xL5cvsDXOrb89/ieOkGNhictWWPG5bAf6Lve8YOHvM+1eQ3UG5fJgV3Jl\nhQkWpx8LlVxXULok17cCE2Ta22QJP0MmoUtTSTxpiGwuiN5PQqQShlOIDXFxTC7LwjxzsNGgwt3E\nlOp1Mk9FATsNlw2rnQmB42mQXkgVVMQyDgVuFqnYIGQ2uQurTi+MIndhLlhO1o4VWI/bFCuNtBB3\nmIeLI7huFVbYz3Bdt2JMkeYzXYqfgvHML/pJ/e7d9T/ZXbd7dx2/enfdnt3Y372njvpuLvRBxiMr\nuNtSAbCxDtkpBX7ERksFlQ5ECk0h9EEl218u1rvd+Vi+RgvwwyNOUunhSExeUF2DUH0SnZCESaAQ\nxi4lMOM0mFs3lMGUQVELT2GrGwYh9IjkA9mZNQGzLWgYG0HeAHkL5LQZn+4U7jWKi7fgbArgJ9f4\nLpBRdo7JYjE/RpFkW77XBf5hbZKtJO+bPKZHFEr+q6aZjmzeBOvLBxT7PYP/O8lXwXpzM8LcYiB7\nEPzok71LnWyiQmRG0LfPmKjLSPY6trKUig+kg6V0GhAJBhG8sZuRkRliNiOKKnrkP7RMJKrZnGUL\npa2+mny1TBq2HbcxabiIHTTbcDCJYu3CZNkgCnZbgbVhBUYPBUmvKFB6cSWm+laQI3AUIIIgqbVY\nmboh3QOnvo+ZfwZM+gzGwWkoFDdc9xHWdj8XFHgBfpWT8IBeALkKH9AoyH4Qqkl2EtV49vlTfnbh\nNThfLoKcnsErlX9WaZV2vYZ2LSfPEzEjeHYc8Oxcxrp8H8QO8z5hlFEjLzumtXQULT2PuMU7IARD\n9gntosWfocUX0eJRNPYayAEUJzvgP+IXHsl61PoeSp8o1WhFN5+01s10u2fWWZXfuFActTUumVlV\n3bG0uXlpR7XbcXwZ/3l1W63VWttWXd3mt1j8bX8u5OdXzewPNvXPdLlm9jfNWlk/fga6LM1NwsXd\nmcXFRf6BFdAbWfyN/llgEsFmpXaYwLkZ0ZNtw8l/F/HAKKmd7HcOISvsNrY5p9GJoO0MLRWI2s3P\nSBuwshSwQ+hsrrKAUM4J1+cWem83wH2M7DTMIr7MCCYqGKlKy0Z8qBdAxALA2kkqZ372aia1avMp\nMFcn/1CZcuTDMZETCT158uFC+cIiumHCCHglaYJ9cAQjOTJkfJJKih00uDOIJygNSGbalyyOYvzY\n5Z9yuWUV1P7H5BAqQE4SR08EeGonJHe5AYlCtlsoA6LdzpYpqGCbFWTkw56WRGcdZRHnUZahkbZL\n6LiZzrFQWXl7GlHxZbDehCJuLdz9+BfS0j+zm/658Zf//T3L955e84eWF1+qmF3xPfZv9bOWwbWV\nsyu/VzmbL/npP7b/tP199h/7uXDhQi4/S6gi37WPf13OI3bJecTEXVzZmogGbMPXugSE0BYGQTpB\nxkA4v+K/oxRjw0Muu4RbFgbsOUAFGb1YioN9RKEKTgcwjmh7H8UxDhf0FEzCGcs4xsm2kjjwnGQQ\nYxkjYTiZsowCpS/nrEumrKPIb7qDQDoNJTyVnQFCEjAHJT3Ca+X8KxlpUA/JNFrRV8FuFXX2OZGe\n5TpDXAkTnSkl7EDVmSqFTemr8AjPqAePwIzXIB4k5R1FpPIdxNhqkJ8U9vX44NprE+OTpeSTkYJe\n+MnDCuLJw8kijyRGX1bCXJWw1ziy75UQWWTjP5yC70MErBIJy36VnCShimxGf5bNsRphY8IkDYJb\n7a49VAuTlZ8fnpJPNe38p+l8F50vLanlh1Mn6tP1Y/XigGSsJ0tX/dT8J3btsdy1z9G1FukQrnUh\n5vgQ8npcM3k59wl1AP+A6gBWcgvFvdKCWcDpQL2aACrXUCGbBCOJBbIbOm/WAky7vIB0Ow81H1QU\nazHLOGJmWwvYGphGyS+2OjblEZ84jRjmuXkI2E/GFvUDAOjKYkUGibFBG1NGcA/b6VF2wmwnrAi6\njWynETs9MnSIs6cxW9EBzFFiXHOYSnzGyKCFMoVQqBpJoZLq5JPrAtIhpKA1hZGElbzSdKuJNWVx\nEzwJ1MRYGM1divyluXPZEErPHZs7ZfWVC9phDq3BAncKxAcRcA3442mwYAqAIXyxA1Cg+kDOgBwD\noUo3vfBu78PU2A8dqg9z4ihIH3AsD5YfxcT4BSbGAegFbcgFPFpxBqEiJ3Oe5RQ8y5HqXvib12AR\n7IU2t7F2ay2CMGov196oZSNjJ5gFFXk6C/IhyK/RA/8AMgo5ZS8izVMgd0FsAbjxQM4gsUrbhoAQ\ngAreo4KCR6Kno5ei16P3ouqB5JHZp2cDwQfJV/rZ7MTTiKc5CnIfRI9om/tICrkDtP6VqNNwMf5J\nPFcgEEpuEv5GNuOPFJzGvDyYrWE+TF2XOlh4tPBMoZiF8jkAEkf3HQDZiz7sAdmLjiR1cz/IKZCT\n6DwkUlJfSRGQk0pPST/CtDtfexXTjqSbH6JvroKM5iSaS+ilX9Tjq8w4iuoGX1ChC2Cd3Ef9QXvA\nH2Cy1Sp01yl0132qWRBB76HP7Oi9Y9j6AsSA3XsoOniUkdTZ6AfRm1H2bnfQgZrZ4GEdo8iuu4Pe\n06D37uZ6bzmKG0S6ETMRvxafItpoH2ZgD5cdnAouMllrUKxVag3GLXUdtTWzZ9hsM2bX1HbUWeLT\n6g1Gf6+8tKmlxRJe0VFdE1vRHH2xquqpzulVBms880KVCgesDM0tnVZoMFxRa89X+GFTWygsVxjk\nucoJH/crTsNZuVlvF6t1qvpYGaL2vMVAZ1levKb45eLXimUEq9HiAva9iq8Ww7AlBhDaZhULSFOb\nkhIbCWWrL4QjvyoO2ktc9iKjw1UU9NRWlhaWGd4pNuVbnSazz+3M90QqzGV5eY/ltZuIXxopADvF\n1RvrXfWiUl8aFv9nCFPv/4e98xBB5vEADVeR9q3KSAHoeeeYkpSSEfNEUvbVaW4yzDR/qsWXfG8a\n2VhGPxT8xlNJuOT74sciqky9qdqvOqw6pVKxyQMsYdLCku+rPmZqWVKlKlWxgfg5Du1Q7YOmNqqi\n0t2AtOSfiW9qSMaEP9gQ/iFhyPkmxsQy4WPG7T2cX/gEUUNOF2P5Vpg3gE+b3GNNsAUc0erZ0Ak4\nzYrSiSKgwmK7Qg5lZ9JSgJTKhMuYcGdiBYNuGYJ5t/uQWzOQvOWecAv0x5q0VKTkDyMgz5eRzkG9\nupVTtIagaNVm8Ed/RtpU/9jw7VyIUlYMThVVOisDleIwfKAISJWWo/2jwgWUDNDDF98jLBdUwwpE\n0MfCZ4JsBCjJIFYDK1iKyzPmufLEYamwhJMFSlQRcmakGIJmKXK2ykNLWTX9MH0OJxAIhoyYmfDT\nJ7uBxaEPFosD0JR3gXwKYkPaGCG/DUu1sG18Con8KtQ0NSq79GBrBchdEKr8c818x4yX0JgtZq85\nbFYNSyuoNhDkLC0UpjYIO69SgVSQdci13uU96MUa4L3sveFl3GUVen0+SBt6eQvIEZB1AKna5Tvo\nw9m+y74bgMldhRyv5WCIr9XCrZuqHa29UHutVjWAo8NSL/70Sk4dvAc2qqu11bLX6vYj1T3lH/Vf\n8F/z4wJkWvf6VyDT+hX/637w/ecxdK+il3rRS/up/DzIVaj9UVhDHCDzQerQUVcReXW19HNEVU72\nkhadRslxFjOyn81rESJIMfNaqJc+kKu5EDL0VlVVayQ8CfU6Ge+u1YY88kwReSsvlo1/+PNSb6G5\nvKAqoGszLAqXN3utRkd18Xc++vJw+5MVL4WfpJjU6M9KAxX5lmJ9lVXf1FJYVldmq6txGV/6lP/q\nXO+qL8NKzKqKi7H5JlBsayFn5uz8Fyg9rkVYUJERBsVsgAlT55YgknZJvuzagh8iheLPAYGNbznQ\nV2t8TJAv4owIbZbQkqRDRih9wFBJ3jJNmNgQKhg0rTdtMm0z7TYdMmnoj6VpaT16ZjNIP+seQKFY\n2aTEenprOn4bU94sBGmzKZfHQ2APyqQkMxImZSF7g0L2BgEQrlCPGTMXippWX5gFlc6GlKTgZw2o\n2HtNDzGW0TglF4zNMZBiM2VllNAPqv+Zs6XiYfdj2pqd5l0bKrm8atkCNeQI3mgdDuyyHLRgcFtQ\nxRyDm+YMXutVkCMg65BWuct60IoTrZetN6w4EWmCyyFUvGajWWAbtV2wXbNhUOfSKF6xKSLcPZje\ndTYbkqVfQyZmyj4KM/w12DOWI7oW+TTSRSTVuLXZgGh3qymknhx2whvCljeAp3/i7b5xz5Rhxn/1\ncvgrX+ngC7Y8NK54LsxXcf8knGVr0atw9mQRPuVVKAl/tjDZz2wMZAFc4fLWZJekFAKRlqsZ5+vM\nVYKcXKAyKA3H+B+IQHZRyQUWK9I2rVIm+Q3+iRrMV1ETSdd18gd4j5DmCrgm7n2p1iTWJzEI4btG\nRo0pFzYnpWvlLCgHY8YOOdbElC0sB4CkhrS0CSiLh0KPwGqx4WZzF8q2M9balBzbICKuIaHLpOC8\nWq+TgULL2V/L+8uHqBicfI0zgPNkrIbGQgTKJj9ovAlgcMA/Qmu+WPkJ0rR2IJMoeb3yHnY+gA0H\nqQgmkrlkU7h2sq5zy1TmQtXuUeHpYkFdbYXH4nAa1c+UeitKSmrnNltiZTNKXI7ZLk9TRZ4ohEW+\nsJlNdX1pSWlJscNZ8LrB7DRbPY5CXdRY6LEbTWWu/K3FVQU1pZZs//4+698izs2NSUZgvfTDsHoC\n60p/lgMoHs7dsMSsl0FfAAg9AX3lEFTnTbksKcJykcHKUoiyGALsqpMAqvJYX+YN5q3Po9iu5AHh\nCIwJZwh7LOdhHoU1nYBb3sllQ1HU9yjs+e/AoLsPBKbd5NGCM5D2oSNlyx8ezd2NfNAH6XK6qFBB\nL1MKaz2ionuLyryWhra2Bou3rKjdVj+rxj2r/v+y9ybgbVVn/vA9V6styZKszZYX2ZYsyUss2Yol\nWzKxvMXOQhYSHCclk/wLZGEZyAwkAdqGYUqWzrSkLc3CAGHakm06g3yjOEthyMyQhbRT3CkJCbhN\nuiQkYWhoSymlwf6f33uvZDsLMDPf9z3P9zxTmp+vjq7OOfe9Z3vPed/fW8D/en38r5hw+Iotieqq\nuKXIZy9rBFdZ4xjOMpUQHPmVWMXeE4r4eiisekxSWVU1KasyuqJdLoJdfCuHpDnsTrpnuRe773c/\n6t7o1i3EVtt/QHs7y2HguaJU0aEi1UKZyEoSirClJkeGeBOgRVcyGLFflv6W4XkDl8E6LEBihm7D\nPAP4rEEwsxJwwgCLYsMruCfPRJtmr0OH/Dmg0G0iBv7CUU/mJgwxxfKND0MBegZAeuRBwIZi8OzL\n1uKV8m3kUbO9EtxglWexm+KXa/ak/7vYSlmJNcXjWFNI/n/lCekf+3/uJ5PX/jqeSZhuln4KFo5f\nAyhI9hYK1gVX5TWARYCzAKEhs2fl5C3NmVHys54oghOeKNJpiOnCqKz0TjrpbzL0GPoMywx8BL4A\n6ayHdAYMR7h0ZEN4KY/ulM5BPD8hGckZzoNcKDKiTCCKqcw9mHKHYFcD0nO9pb9KvCIVlxJdwlNQ\nwlcXry8e5SCvpG/S36p8HjL6JYQ2CPBX0fbnWkjoDf/bEBkFq9+OhL3+w0igEPZhOYOfht8Fm/JW\nSGhnWB5iGoUu8DpQVO8BjIZHsyRIH6AfTNZidaNdquU/jOG6z74M7KT77cewIKIwgB9g+omVdZfB\n3aJsBzbOTsAcfVP5duyZEa/RFuj6u6DKKjEbt0CV3QXH/dO1F3lCemK4M4ywY10Q+wcZyoQ0Qs/w\n2ykA0TFAD86u/oirZlz1YP+jGQCXl/Q8+1LU6yjWaORmgrlRairLOtCnN9fsAC3qZJQfIzd3wAVA\nF7hDYxxYhpFFoUDN+rC7dApBritjkTQxwN4u8mBLLjyztKOsvbgU23KhWWXtZRsndGLfrqLU2VSB\njbsK9lXPnHpyTy/o9HSWzQnjuqiw0zM3AOW1s64i346LtnF7cN/L6oU/Jr2wSGqFmr+Iw4AlVhYL\nx1TYy28Z3cvvGT4rJmift441fXp8u1Y8NsW3G2VQLaNIdxNC17opjuMx/+T4diewEjoP2Av4VwAF\ntTsIqJWD3R2vfbNW/G+FuJOJTcG0nIly14QNmilXR7mTw9tJkz3Y4aAYd8QtIe3H9sp+6HkU606K\n0clVJvHa0HeOa0LfWf8Hoe+Y9Rqi1OFvZOIOPSYyruObhT+DY/AsdMmNZOE/lH6CbYO3/ExS+YkL\nsV8tUyIa+JeGbWTZpfCmZl3uiGsG1pbgRdPmkbmRlq+eNOQ3apWJhyIRkbV/ob3u5pjn4bve/ZLK\neOV9dhAV/jzitkRHFgtXxLOCVbiA8w64pafDeUmYkOQOkY26bLLeiivYreMQuFlgZOSpkR0FDUPE\noWoNpQy0aj4HW3bzSraWbWLbmRzCSqe4HDxPihpgE/GlcCVaJAruFaDg5t9jCQGHrvSA/giaxmR9\nL5Tb53PAEZizNmcT3NBzBnKO5JzMOZ+j5jfk9ObwG87T/G981Qh1cBW2T7qR33msErqh8L2OJziX\nmw0eD1dL8DJdKauvsFrLwp7GjqlTesR/jiy+/a5Jk5Yt/rOJwT+78PADlz5P707P5fQjktN/ZORE\nh0PSWcCjeXLc4ykY5MICxQ4h6QhQQaQpXILEEztE7knwEuCi4gKDS8YGtpXtYqqF6VfZaTSB+RDT\naJQnihc9H8vj3coR6AppK4Q0H6rsbrLofyhnQ87WnF1cGgOv5pzOuZijIj4Dng2e/iIkM2A8At/w\nXhDGDFiOWCClt5H/BX6La5IK+ivcUXF0qR8nkS9dRyAawT/yc1WR+Eu+ynEJNUKrMEdsk7nNCipA\n5Y1QpzMBjwKSGKzvB7Cp5D+sWPRJScD9TBYeSIikXkgQc4US1uhRPHQKMAhYLNJ5XLpAFQRf/lS0\nm17AWhWZrUMPBK9EqsKCZfwIvRyZWS1Vy79CPKKpYOuURuDYNwuBWM/cmlmrzuQda2ZG+yQ7Vzom\noPjQM+G+gRgKJbTJdH9mfymVM0REhEi38WyhhfB763lqvXzZxRVc7LLO7EL8An5LQrb4P4LnPa/M\niHyKE5bC9nIzEt4AyL4OOYLs7aBeIT1E7YF8dg4wtJaLiAuHmFjpPnEZ1s50+LqVXEZGQ8zLJqJH\nAOdpPMxy3MBJgpegkv0k1CvS67Vb+IogvdawiY836XWWzeA9XGfdjCO6Dc6tTnwX2RTBn4mbJuK7\n5s3N+BTfFMctk7ZOAtX5Bu1WZLPBsPXabNY6NyGbr9Q9hZhDa5s30e8nbeI/dAWYy/Zp52af8v3p\niVy77bR5qgsKqj22zN+WIjkGXFHm73DoU2/xFIlvF338VmG1x2r1VBdm/lYmQ0VFIdxCf9n8T7mB\njx3ERUOca4v+65FIpMuwvbzPtAanpSnTIfxJmmaZxLHGrjLjzHi6mX+5mv+MxrFbmVr4F3Y/r0vP\naF2SOZny1aOlp89oL+MtnjFdRpnjaiDNInMoGFeNN8jPFsrimVJ1QiEfK16jsQJaZUjoEGYKt4t7\npFkLePnhOAfSM7fh8JAtiCsDBLkDnUGTNzMMn0PpoNCERe08SG+tkI18Njo6PCqPDtK0zIggPQG1\ntRVwH2CjosAqo8SAoLaoy9Rcd4cSC02M/0JRZ68JyhhGYFbpPR9+5rP4ynw8LU7GOiOgOzRXe6pD\n1TyrjbN4BrMsqU5+cydu7rR0lnXymxdYUlP5zVNx81TP1NBUlHsnyr0zMwAt4i9zUWYAauQfGkcH\noEWZAajRkmodkja2wjCIlxFAGQFLoCyAyJGD+HoCL2YCipngmRCawJNNlOwYTLVaEIyJZ9XNf9mN\nX3Zbusu6+S087VY+4fOxMHUz//nN+PnNnptDN8uOV0sg9PEj1lVDlZSDoXs1Xtjy6w5UU/BCKYIf\nTunSiMMrXme0moK57pOHLENmyJqi0qwY2K09qD3OG+zA8/q9+sPwuXveuNd42MgvducdzDuehwv/\nQf9xP74K7g0eDuKidm/t4Vp8VXew7ngdLiYfnHx8Mr7q2dtzuAcX0/dOPzwdX804OOP4DBWNUMSc\nmjkOumr00XzCd5/0uy9i1GILmqurm/EvWlDVVFbWVFWQ+Tt8z42/+u4Nv5JHsCPV8Xg1/pU1YaRr\nKvM0YbBq8twgnW24wReKj21YnC7W8fFjuqTC+DGi+Ehe14y8lYYJAd597yn3qYcUN1vi+JetJmX2\nfJk5vzHC7v75z1v4/9nNwJ8LCmciyo3QGLJEMiBSGxH5YzlKfrEGMtek5TCYFA2wy5FareQpa+Dl\nkw/USHbRkRRld1kNsb/o5AMb/Mo4BMwb5INpuaPcyuvjUOpG/rxUs5/f08KWPv10y+bNVLcg18uK\nFL1M8+nxLJI41yWVDPEsKAqSopc5QjcIbpH5kAlu8ZmCWRB19oAc0GIs9UMmjgXiDN0onIUcYiIT\nzgJnpWKW8GEKAlookSyaoXwpQSwQtSLd7JviE1dcG4zCek0wisb/fjCKj19jf3698OL8XYRGPmID\n4iBvnxPYc/IM99zoRCuHJzPI5G9PaLdpNTLt/sDL2te0Z/gYorDuG0MDZ4yXjSN8DEmbjR6juKLf\npKbVvJ+PjdiHMfs9fp4KyxQ/toGlVmzwnCm+jA2eJ4q38T/9Raor0n2hzNhOZB/X54lDcylgV6Si\ncjKVKyItClQ3GW4bInMkCsdXYaEwH1Q379hGzyZwLCE9hXOHO7EttQlgB/PNEfdJ93k3NKal7lXu\nde7Nbt48tsOw8XEoxEuyLPAna87XQCcgthsHeBO0AKK5OUzRHlDw24BlKGw94CHAFpx0rC/cgs3C\nZZhBTyF23Qb3VpBGPoyEHZgzl1Wvrl4PfvchFHeq5gIvrnIcOx5vGmqiJ9DqAlmNXO1gtZk1RUFP\noa/aW9A2MdKRM03rbewMBCdHSgp81b6CLJfenKIJAV9VXWkk2VKfE5hU43TVtvPBrKYi0OBD+6gd\nsbA9xLE3gQ2TPTeZ/KUvCyNYfZuxNwV6dn6NOOpZhnZyB5UsWi5TmXJvTFtJ5mQ4cNUZDtwxzeW9\nDLP1mMYSRmN5tHgjGoscP4Eay8wQux45H7WcseR8snlmptEYy0cbjQNnWw4i6cdL25eNPEhBB4mw\ncjNe2uN4aUtcK2FOt2nMCwThp/QIgF7lesB+wFa81Ffdp/FSwakkXUIqfD2knWhOu3FsuwsGvHjR\n2INH0yJLlw2AS/Qxs1soXaTtmQLU1o3ankI7I6LSTajeOjTl11HCYcASwFrAAOA8YPP48unYeDus\na17PNuztaGmrqtehOm8j4QSK3g7A0Die4NCRp1HmZld2pFI3Doy2PVZwo8Y3yoY4p7iWt75QybWt\nr75SHp+e4auhuxRf41tT6pC0EcYVZ9XvwbjifrWsCcvHbUNyOF716JHWYqjzZ3MyjYSchIzyAlGt\nxDCXp9IA/8fqWlq+3tIivvLOO+/IZS8aeYDtpFiCOuGv5WiC14sZSCzEcEwZSGkOaQY1/Es1RUnv\n1/E2+lxONpZglrGYQpUjCGEP68NKb1x0Qv6NpknTo+lDmPEPEX1PrynQBDWqFYhBiH/f7uiYfQfF\nIkRNeT25jHYqMtrCnzKNo0VoIurLathYDFHUdmISkV5QgbBKRQHbidmNJvMXdDxVy2ubhMSeu5HE\ntIrEeBVVMOfsU6GKcK3Xq7DDQJXXwcKzT4dvEIBPryvQBXWqFSyi42LWedmdSu0zgh5f/+e4qAZe\nFl8Tz4iqhf9tgdNLp9c/hnpOPkv9n74E21UvgZ1W2gsTmthp4Yf0HLeDgRQRVfhAda3saRMzDbd2\n6KbkSS0JmsyxDJnWoK7i0CeK2saFuUGW47iyV/KnJb/1NCwWwMYqXsYq5gXxZcUh/3pxL1ElOfgl\nakL+oteI7hMlBrk8IsuDZDHygPBD6js9qM/LIrth0TPHRdu8cQkupYS/xfPewZ/3OXreEGQNV3ox\nOwZIT1Dvzzq4ZkVKbma8r99B/Rz1nMbhVr4WdQnbU65Qv1N2b3RZYMx/CPYcZzC4m2E8AM8e6dHC\ncRSq1/U/pIM1nKVpDXQWdh5T4U+0tF7utzCZvxBbkk1opR9gFNeCZJqMK5vpow2mxJNxT6OyIbsw\n3ZjfxZeTiteeQn5HWztW70wVaxN17sp6T7HDZCr0R33WdtbuSUbm2bzFVm2bpmTCxILhDwX1uLil\nE4V2VSNFLpUDlsqRSrNRTJUApv+1yKXtQ+nF7fcjBoGlnd+WaucVD7cn23kTf49fp9qG5LBDwUFE\nGq8bkmbV8U/NPLWZ/61D6PPUpJA0axJbAa19BLENZrYuasX6opWntfC0Fn7nJEvqpiEpBnPXXtht\nngWEYTG8uAM/6VzUCUaETixPOl/ozOz+/A/CnBZiGzS9JvpElDc0rwVPchYWocloG9YTyRCM5qKW\nVIT/EMEphYglUhZR8TVhs7yf2jKIIEqTiL4GvvE3DG6qUTlU8ib/1cFNodcrFvTXi2yaq3PfMLIp\n+IPSOfpCHA40URDTa4Ob3iCuaRpxTUUloKnG6rg2oClI7saHMU3H8ruh/NwwkOl5QB/Oby+SyxDO\n8jpgntsIOAfoBdyKXa5zgCigG9AFQrlzgCigN4HFEeSXYbuTHSmkGB68RzFl5rqWdcqo74QShhT1\noTCk52JKsenupnlNXHxN8Z54X5w/zgUU2YSCLgCmJD5DQNHsl3zOozWTDgYoDu+nhxJlwanO6nKb\ntdhrXdjy7Iyp7eEvtK28ueVTA4guUeUVu51Feepooi0e1fzzgQM0txaINcIp8SJ4L9gjktGJ9bvs\nBUu80ljgbuQrSJzGa8EZZg0V0C6AtAjqTAjkcJetIzhUNON6m/UFfg1jC7g0pVuLZsKfJFnEe6Zq\nCLYaORRSj85fQKIj9eLUZX6GlCppiuV1583LW5q3Km9dnnYh/2zuNs8zLzWvMq8z43OTrcfWZ1tm\nW21bb6PP9h47ztpX29fb6XNBT0FfwbKC1QXrC+hzIbiSlxXC+oLyK+kumVeytGRVyboSfI6WTi7t\nLV1SivBeWt5K6LSoj2qGk6F5qNk8qllTXk9eX96yvNV566lmTeYec595mXm1ef11axYr7C6cV7i0\ncFXhuuuWjLCo80qXlq4qXcdLtn3CblbaW1joxT+fuchrs1cUmc1FFXabt8gsfqWwoqIQ/+xed16e\n22u3ewvN5kIvrTfKR95nf8PnrnqxWzIjIix5KyEYLLmwgEpWr+YLIjNFh5XN9aRFINQ2W/rLuHJl\ntqTqB1P1ISkJy5BWmHediVCQ8ch9kTWRJyJqZdgkr4/M9EYhJMhUpM6ueIHBPg2H6jhXNciphpBU\nYK9THCoRzkTE/NBfJF7BfpFvSHrfJx/r+LEN+n3olEPCf0KPBI9X0vAQkw/6DjCNfLKX/gF7i8GE\n1bQOWy0P5j2ex/8M5B3hf6RfocmewPi0z3oUrRXBFtOnnBeg7VPIhp8U/BIhG45kwtZK57L60UnA\nG3BM2AnoqcCRIa4uUlzZQA9iBFzCAVYTzCNexy7U24BGuKycphhw4I7hQ+Q+TJCrAafoCvXewnYi\n2vgxdopd4EsfaQNWKAcAYApL42g2+1jSqjw8Q95RPNSr2ILfn9X0aD+D/DUvEbjGWDjSE1CoOFR5\na8UuOKRMwYO8OfoMaRgXw+kKT3EOD3AScAKxISrrG+vFFSwT+NgJw45rSKj9gUAmZo/TxZLmBp+V\nLy/q6jrq2zyR9orowvJm+03V9qDHNrEyaawKFJfUTyqvn+tid5ZU6K1uW3mpwWLoaPDHvJaqhkCZ\nP8dWavd6csx86JpQ7otWWP11sPegdk1+AP9GvD7zFgqCXpDek900RWHSyIPsP8RBwS7MVXkkfye8\npDp5G+/kDZC397OyaXt/Hr/OUcHGULLTH2wmzB1MzQ3RJmOnJTV9MDU9lH5i+rbpIrlPSVWdfuW+\n2sFUbSj9aO3GWhEZpyYOpiaG+hv572ot/TfxW7vpVukRxFd6B7ChGyvDenlLcjbvI7MRGHUbHJqS\n9bPlJUJ/DrsiVcyul23XpTX83fTb4WUsJzlCqdnkMCVVJclot1H+YWMoVW/pb+Lp3RXEKroOBT7Q\nLXcgcofaTFyfmO/ID35n1lP7EjYyDsIg+yAmvFdghQSzJGkTYB1gB+Aoeedga2AfIIo5cQlgAABi\nivS64Gb46dA2AbZJRXlzYOD5ur11h+v4gnFLZCfOOk9FLuDPgcirCMW9C4ukJqwDd7bvx8JwPoJT\n3YUT3j9N5rAcJ94HAKdm4AqwG3B8Bjx+Zh6YyX9zeiZP2DULTXYOKgvQz+XNOzgXK+WlEMG3III7\n8PTk0v8t/ahBzEEIYT+EsB3PehJmWevKN8Ms6ygJBA9/hMNA1DfZ1+tDWEVfRgD7AFsyZvbSBsDz\nkMFAzRGKLE3RrEFXcgEj6G6EIT8eeRPP/ndI+D7gTkiBREGPPxXy2N1+EPJIIGEp5PEB5LEMorgI\nODgVLhQzTs7gwtwxY98MGJRBDgOAHYDtkMg5COMI4A2ACmKxAyo52OCJUyq6MiYLgVidalwX1+qu\n39FlY4/R7v7zkgkOj8/SbnI7TNaiCmvzFo21yOfyVrv0oYo/r46FA36Pp7HT13F3Qbt1SrW9qsLh\nL9sQiCQm5BYVWErCrd6OBWb2VWOwzOFx5evKNPmuYrOz3G3Tuw/lOm0mZ2mpvrLK2uRsm1iXdLib\naqpvqrI1JcpCwdyCQImnytJhaw03JO06W3GgKJAI2mMBrG/auJ55guuC4GB7ERxsijGOHLjENbpz\n/YJW3rO+rB3RGhbK/HCfKZoJDkhMXHM1HTIN8mVxvxEEN5Z+M9dcX8CEowQKuaxwtfExIC80ntWB\nr4zyLBQjBNqtqcnUY+ozQbvFcltvKjAFTVx/HkfTFoscz+ykTYZS/R1lx+zjF5W9hiiHN8n/aV9G\n3yclu5+pwFQvxTH9vAYAAYq0FYBIVZn9E67kqkPpVvVMdUY1IqKrqx2iyK6KgckCIw2ZR+oxX0eJ\nfnPUZInP0WBdlLRYXkG54V+Ka0VZw8GXGaJ66Q/QY/QqtoIxL8hb2JvDv5zNvMM72HfFxz7+kvhY\n+2gMTYpTXct+IJUEsG4dwwCRhFfho4DnruaCIBqIN2H4SNaP20cJIWaho24cRwhBHBCZhyZ2CDot\nGscGgWhsChuEndggpPPI+BW7PPz2UvQjsjDKMi0QycIxABGQn8J8/SGgAAvuHMAHhZmVx2GYLR+G\n9+x5wBuAw9CO3gD8AYDY59IpjEgfAo4DSG06DtiPEelVwMUsUzi2lgderTpddbEKZMvVfKFxtPaN\nWhxZ3Iq69mVDXRzNslWczPjppLVOJ9gqfl+oLCvSpzwXcHx1CpUhb3DyAP8I1TqdDb5+AZU5TUNm\nhp5C3mLeh33uN6rerhKvCbsec40NeCFH/rNFVn8mJojXFAKICoUQ4jpEECzG+4pm5NfsXvGkoBL+\nVfHPuIKGbBy1mhJEUmCkK9Cvjapirn5fvfs1jhqNJQvBOtorLBFWCmuFTcJ2YUA4IpwUzgtG3vQz\nrKS9oBI0gZ62ly1h6C1aPpKzfTBbewPdZQu2AYJik9gjqviaF9HE5XN93mWoXcEoI92tmscrlN6p\n2q+SjX5a4yzUnG8TT9jJPhYd5p9Ufyn62WOKT/sZ4QWhWXoBFtqHALPA+oKABWnEIUQjoO8WGaDe\nGUZg274ICa0G2XqWCXN5nlV8jeVhd+1hav1ofKKz2ahEENhZTLKz9Iv14kIlQohMqJiNE2Ifkhaj\nCyTt8s9KFfdLYk8yjt09g0ZRqgYPRao0JIceIoUCNhqMWCNKiVTJYVUrayWrpb9AJr5ZD7s14jm9\nBKqsw7YT8HA5j1n/DxTJBVU4AnDBYe0Cri5iOfAWYCfa/YNo5ofdJ3Bg83t0Sw1ObZwIjTHPvdQN\nma1DKedRyjrAryhnwO8BGhwyHrGBidc+aD9r593OhsIoisz5bDlbAQc4DPS5l7lXu/ltFISjgJfE\nvNaIo7wxIscwkefdMUFMdu/8ePjWJYsX28O3TKqdXRqyN3nroiX6nWzm8LstLczWMi/c2xYoLou4\niv3NycLZFGeKj6OTxD7BLZzewzQ2dc1ogKnMGx0TZwqmmJJFIJNLaHDb0Cjew9MJNvzAthhyPaR4\nDtkpIIqTXk/hoLQmE8xcID+gzG5bRm0kJhFMKYVyhBOTpV8nM2XZBrG55hykyEeWPgQNXg3VZzlg\nA2C+ha/yBqK5k3N7wdONm5ZZ+IITbLciAlDRqIKwvDSGkPwiXGLxdbn5hWarz6yqnGirqnDefnv7\nOrZl+D/d5fm6XP1N1tzicIAFWr78ZdlefKRYTIjvk13Ccq7zpl+oe7kO3HBD1zUaHzUVh13CGH+8\n64a1IbsE/WeyF1fMES7VsDH24LJt9hTALsB27Pptxq6fbBMubcKIvoM2u7JRHaZmQzvsgj68v+BY\nAXTm0iNwoSJKnyMYwrHiTx+rPoWDv4MZw2/pVTpz3IyZu4m8gshYklyDUPZTKHuLfiesIDabdkB5\n3YGSyHx8B4qDu55ifC4bO+yvPoYiTlcruZMB/LUG5tZPNDB313fVZAzMneHQBPunGD+I9cMbSgNO\n/TgL8x+hb/h533ibj3Ex8XapLKiqgX80he3p1/Ilxn0Kw8dC4uuAZxz5IWH9J8WCZRiDYiHJHaOr\noKW/ii+syiz99WplaWHh79iSGeHIeRojHLNUyvZ6KYuFtEGjnGAMga8xyhNyo3zQoKiCbkY8GFWV\nYOVJVYWkxXweRcCsWvkM4QQcdrXYy3odqg8ZbDuxofU2rh5E34VXU3pr3i5sJ2hwxrAUb8fBO/PA\nEttK21qbSj5sSC+xr8Re/0+gI96KnQWdy+XiSwAKV+XikD5Rcq6Ev+rekiWgwDiBl7oSgJAL0o+z\njBjnAVrsPCDqgrSK4i+gka0CXMDh/kVspbwFOAatSQ+Sx1dh6XMMmtIxMDh8OBFt7xQeUI8HfAMP\neAGPdRrgxlOuxgNuwANuztuBB1ySOTpJr7Ktw0BVgCF5Nfxh9K4CPM18PN4QoADPlQMYgp31CSwl\n5wH6UOHVgOWA04AcPE4f6r8asBxwkQCPcyqQeaYjeBwdHucoHuc4Hof4Oz7iYItkwkmM93p2jYae\nGBvty/vDSk9zdWHXpAmdztay29uqpzaV28prC1SlDT67b9ItdTMeKJme350sjVa5ShvavB72ZJ6n\nwdvcGvSXNccKQl21JRMR0VhbHm4pr58+sahzmitSb6+c6AnGKszkD107clblVPyhk0KnyphqC0l6\nEABW1fPekPNprtCgLh4kJ0bM9Gqa77VDSB7jD01ESRZsTKaq5H3IikH47duG5InlBWyQtML0uz7j\nEFbIC8LKM1lfJW+bINg3V2eT9JHf1jCEfOI8hzhIEtpSbXyUbsPhk3QZyvRrgMWAJM6cOobwZeeQ\ntGZyZpzOhtsa6/t2td80+a0lyW9a/1n9pkvoUOs+NIQzAEsJ7YFaQgMzLYss92HSMls8Fq5WlhBD\nKihRpcK6EgrmgkEBp16tCN5baWlF+a9iPd0g59IQwglZ49CAudHTGGpUUSbtg6l2WnB1DqY6yail\nsYx378llvWVLynj39iPm8FyEQT1HvHIAJ0VFBZxEu+0F28DbuOoGucB56oY4fDkNuAQ4hvO1Juxf\nrAbsByxvw+DStqsNPtttp9sutsGPog3O3ZD9euxx7G8/hj2O5bje2r6rHbuQ7ReVbaAVUi9O7NZ2\nkHN3x5GOkx3nO+Dc3YHq4atVgB10Uyfd1Hmk82Tn+U7chLO97s55OOfb0YnhAk+a7i6bB8+7GK5P\neS/A0K4ADzqfJIBnpEeeh0c+GRz7yANHmk42nW9SyQ873kO8UgkJM7bvakcjll/VdW1wJH921JH8\n4/6CqkSVp6TSHnInq4vClY6Qt67eVdVYGplmixhrq80lBeacgurykuh4X/P7KyoLKmxF5f4Sc3GV\n29toEPXNgZI6j6VqQmlpmdFWaDIWuczDJaO+6BWsiHXzOa2e3Su54VpyFotLC9ayKcVSmy+3bKGM\nSbf0Aga41grZBYRWfRlTbqm+gjjj6kOSs56uKkAugiy4Mg2eqzTOCUT55OCq6GYe3gmwvjgDYHke\nedKTY9GsGJDDAKjg9gPzkzIcxeTKN+ViIkyFh2R3PCcLUyfAotnroU7oDcEd2s87gd/jD/llX+hK\nayNOJWW6GpXC6HEyw+OR1tlddj78v42hfh4G/RMYX96G0noK49OlKrSfydjOCVhjsCA8RbOGvQA/\n+yPyIcIBygBRmdMnqs6BdpFIil6to9H9v9BAHrtxe7BPHNsexMLyiiLvp7YAmVv3pJhkbvF7Qolw\nSTILfAQ3w6lHpuETvpCy42gPjzILuph76Npjb3s2bM6A2eAxhAw8TaPElMWXJXx8C9EulmySsgxG\nKQ+RU0yTukfdp16mVisu529TSBUcAs/LX5q/Kl/D74nZum3zbEttapDZ4qR2ngrM7PSVuls9T70U\nPz+a+fkAwnufxwH26nwU0Zw/JX9+/vJ8NYpTDuPUC1XEQEpuqNFYRA4T6Kf3UK0yOT2u/Mr8/Aqz\ny6Gp4R/LnPyjtcLCP4pJm78kPy9Hb/bY7JUl+WZ9Tp7HJusBLKiCbUme4GTbUvkhSa0BFakSbZer\nSSFsgW0kWwjF8oyUqkfhm6iBFizNhNXGNkBZDtemFF9/RasyykTnTJknFaJwaQ2WLwiqKc0CMXH+\nKI+jmeLGclU6hNe3puAa9g/rEGzDNYOw53aQC52YC0164Lj4pngJJgbwdEo7xEp4D2qV77Rvai/B\nccWhrdTy5IcheKP8Xdw41bjAqFqRThinwQ/uTzAWMBiLjDU8UXoYxgLfMcokEQ6q2Xt2mDzYLfYy\nO280FrKuMjyv2qs6rDqhOoeoVRQ2bx2gFxPoETW4bDFhoAm+qjmtuajBq0YUEdkfKmmQPRVQS/77\n+Ub0UURvTb9u/BUqhRRYSqu8FPgzYiMmD0QALVc91yL+TeBvxJaFf/VXCz7+zeMt69kUFmQLhrfT\nv6eHX2Et0eGn2JIo/Ex55/ktHzPL2FelQnAvLabVR8bcBwqrXk27ptbBlDVE72TAbPVYQ1bVin4L\nbaj2e1RXpD956G6ZNEMYPSy9egMJ4WtBlPQ+0X7aidHjACTzvoqsaPpNXA+wUDpfOUil8h25sLt5\nGEvu7wOIAeMpAALLY95HjARpOdE2QIqIKsVf6ztI6KOlMxbMR7O7JG/mX4IdxDKswuiUaBVG2T8A\nKkG8shbrZOKOjOLjKlytxADYDObIquLmYvipH0b25wDbAUsBy1DafMBFApT7JuA4CgfttrQEBb5B\nmyfOTNEoK73KtQ5GtmB1KS9vZPKxxTVMQeXst3yadFvK3BaHv6E4Ot0w3fyXt9TcnPAWBiNFZ9gD\nc5jH4gvWFpTUlVlbIvqZC1x1XXVVnS1R90+VebKc5slSdpfMt/UCOU7iGc+Ca+ezUW7NwuzWiv3Q\n+8oynZJCQSu2htdjx3o+G7QzhsCtMkUWefdKGqT+SpQ7/41JsTJEiOmt6l0wg72E934RGtIlizLj\nSYux4WSH5//vcaXB1eTMTlQaNFbiGBorhRAKnF2SX2Hv4jXJ8kPtHM8PVQijjrdR1nlo/KP0WR/g\nisJGUlkghkrm6BwuR8ARc6hXsE+gfmLdN+Z7YuU3InmSY5lwPR6c7x7hB1KRCe60RUR+2++WObhf\nGMPBncLLGgSMQG/dWD5u5ZLZrMkyKY3ttZKK2JOkl7An+wPVW4jhcUlFIVz67SIOhbj+gsXI1NwF\nueKK9FTDAgMX8iraFIHxjOIPsg7tvw9dqo+vKYQ02PXQArBlsip/HW7B9km53y9zuvsp3IuybS6z\nvbOnxhBsG0vqKxWK7SzBNqsa/jjQUuUgiu3hb9ri7pERWU50rn5C2ScGH3Je+v6yR7FkTpYxiqtz\nzX2fo/sK0ovK7uP3Ddzve9S30YfgX4j6oHCdyr85mP3NHfSboPQCF/XAa2Vnyi5DFyHquRdgbGJu\n4DrKaw1nGi43qMbnMVruGspDJy2qyHA6IC7zX7P3R/ZynbUI7v2aEE3Jg5h2GbaWQ2Tj6Sh3lLP3\nh43TGmgPlMPrvH3omGaPoGbqGmXXPweNHCqt7EOHNj8gx43jwzosU9WMepxAi1S42w/IUfl4ZyS/\nci3gvYzt9Gs4VwkD7sfETyT6tA54AhDCxxSuLDkZ29pxXgvZZqYWiGQf8cmko7B2364egDn3CfU5\ntagEXaStUqEPvPqyu7NqxWjEsz/A6gQRonkjRHQz/kenduEPFlniinKvKmLj/zHn1H+e+S3xW9PY\n68Mr2VcERVbiK1xWZvbkHr7s4bJS0SLSPCTdj8F7FlwQzprBusAfmeVRVbdj9UMcApsBJwC/Umzx\n+WJIoyZjhjcxdLwD0+etml0wfV6tWa/BuQFXzCG1RZnYjDDjRqcCAbNBRWulPAs8RGT+7EF0KMzB\n0hOKodpC6WVAK0zWnsOVBVdy4KxrKPUz+9ASM9G0+jqkNZ8tx1b4g7A3lqPW8Nb6CyaTWKsGJY18\n73fxCA/iEeZrloOPZS1tvAEoZNEvKMgMMVvzNZhRIHagJViyDBn/k2LN43qisdMo09lSeIJ5ZJIG\nEhcKOhiEGIib8BQmzzewiRLAhkSAi95mi8j/qWjVo7rtHvGLnV8U75nx5NQviF+Y+iR/k19mX6B/\ntezR4Uf5m2TUcX7BrwziT2UPHqxf008I22BtdQbL2FmCTLjAV7J78fLuA/wQQOGeLHAoFoeSprCY\nFGeJi0XEctKuSJoR0ek5MRPPScfnTkz/r+FZZsH15zktnH9UY8M7aIbS0Db4wLgAMYkOao6jDaiH\nMiSdK5KG0VBgmoWye2T6rO49GHQKENAcwJtYrCZ1oDrMBIJTLxxAyK/FOkTCGUqaERQHca3kkDm6\nhUlTq17mIkPAHO0KJRaO1JyjCFx2rpRm4rAMSpBk5lcDLxheNrxmUC3McG8tlG7DsdkJwzkDkX4k\nTRtzn8tN5crBQ7V8wpuVuzj3/txHER8SjkeSBTy6IcATeJm0LYZYQRnncATMGHPcmGmoFC0IDTUn\nFwFUpd9j8IgCenIQQybnIiKJxVB7J6ALX6lxpRLB8SzHlqoCgCw5jbU473URVQesi+VQHrIpgKRV\n5ZDujWM2tEsX2mUfbPJOCRfQSpqIjQgNwo8GgUhaA7IGp5KDmkpVcBt4A68f/EhSAQAOIFIVXteU\nbISOPjTvD2HP3pPTByISP8Q9GfAHyPzDXCxHTqLsVcI6lP02WigqI92KZ6HYCyexwF2lXQc+JkhD\nWpCDKJsRVywCS1ud9192L3jsC7d855UFz2ye+9GbL7zw5kf//u8Y3ywjFnaC94V8MYklHW/wa9Dn\nt7EX2Mvo84vwjPdm2UT4OEgDXNZ9u4/iZ+JqX9bD+wTgV4LiWGO2IEyUtAUrAzPGv/QTOdvwpkZo\n8Jcz7IMT1y4K4AP4KBtio4micljkEzmu/1EM8UuAKwAjBrZ1GWNHaRaH/nw+EDdhb/81rL7uA0Ab\nG7MazbQoohREKDpBm49aoM7S3vHPcSfgAcA3BHkhynVKraXfKF6RT+V+byFtY2C/cEw4hdC41Dam\n4BcXs27tH2JWpfmVGqEOAFd0ya7mTXev+jAmtL2aw5gGTmrOYyh1ogF9iCPWXbCBbLL04CCQgo9c\nyJ4GHgCcBvwRkANpLcBVDwRDUsjJh0XYL1CV1wGHAT2AQpwknNJkFstFxO6VJwudKy2AUwA9cp2S\nLWRB9jUdB3wfANrYGB+FZWrnGG0+xFSRD56YdcnRdpPZY9Y5SrxBc8WhObPZX38sRZOiJmmoDS5g\nb/J1DrVBWuf8TI6x+BBWOa02WuVkvz+Y/f4O/v1UPizaXra9Zjtju2zj2jDuTntsIRvvQUmoURww\ndFa+XPla5ZnKy5W4B5RynspQJe6pZATyQoqNDPN5vk58RShglj2W0Vi+g3K0JOg+96Evi/K4zVMK\nhmgelCknFVerxTQdk8gEixJ7IndI5gtczKE/h99kyKWgEltxUINIxOJCOURFyjQo5VlylZ/ZlOAP\nY8KhG6+2N7baKa6ZNYRFvVFnV87NTEMgejDCN13SU2r6cf23cCQKPWXgsP6E/pxetTD9Hf0emCno\nyI/eSsTDdOYs7aMh5wRGp/McYo0Bb2NEhe0EFcJMZPzZG3+re/oL/37rv/3brT985Gndd77T850z\nNxujrHf4e2zu8O6o8eborl0wyxJcHL7Jx5gcdk4SsHV0H5rbZQB8nSQPb3jyglX6BgYZiqb4AOBO\nrEVgLSIq9lSIZ5u2Mx+WchHWwf9ItyDp71k/bIozgXIhO5nsAu9uUMoFRV2Rtobr/+kW7XRsAyxE\n0j9p/5mPmAOyHRzvus/gHd8D+FvAIxhVp2jnY1QFtRwqyVczulAaUxxoTPBm4eojhQGHAPcDzmDo\nfgJwnyEz9IyLbpt14NbLx/78DX4HY/yXhScxxr8P32G1YBd8fCUrD0m9gJWAc4BXAD8B3I57I0KH\nMAccoypLv8jz4++eokj+ADCELaUWzXTNbRrVijQimfNh5h3Nn/ifAYOmSFMDptWHcOcUjbx1gkUg\n8XDBso0vtSBjZQVdoA1CjD3aPojxdJZx75IWrcalgSUbVzcayZhtw/CvWTFffuUPX2F3sO8Ob2kJ\ns2UtvE9Tm6A+/4txNs25ik2zf+R9UUuxjwJsZcobklq9vP9o1FfgasQX33zeQMx3c9I8y7zYfL/5\nUbN2ITko9RdmDpzHbTVlQrVQUBN2heKZyKfG7ytPSZsQimXeOvI9QgdYB8BKIx3NmYxZ6yO81B4s\nY5oBGwAfAXqydmMfkd8aBqGPyGsaOwwgy+ZS0zgdTv5nu3MAJEaaYkcxPhUPgM+RfG+W4MxVi/AA\nfdhLyQE/wq6yA2AozC1zl/G7d/kPgMGxEKpjLgKK9AWWwZg9J1CIuCKI7rWQIlpDi6MIYLK/nBRF\nLbuzVV0P/brXsQQE1X0oehmKno+QPr2BJTxHNsYIgWxlx5mlTRKZM95RkZNT0RHP/J3+ZxPz8yf+\n2XTlr/i1Sbctq65edtukzN/2yff8VSLxV/dMzvwlHculvOsw+/dUZUh6lI/K/bkqtOH0Ws0mLIdz\nSeeSuaUtg9JKDLFLER34pOU8ZsVbLdhYedzyLcvzlr0WNYwCQBpN21cbOZCBO6jTB9Pf8jzvEemG\nsiF43fGLanJwDA+mwsomJdmmZFqOm39wk3vHBLfs3pGawJc07IqkkRO4zs1Vtvdg+SXoLfAnM8lf\nmELSIqxtKQQmIiEh5NF7FuxhWSyWMgvvrW5Lvw2GLu4J+IEzlD7kHHTKM4KH1KYKOkUOkEJfTaPz\nKujBWwAxLHmex7uksDHnAX/gT5s0wVgh4Iq5ul3zXHxhfw67lLfiwCZGERYBsKYZWBVeF94cxtbF\nQ8gwigw3WTN5YddF+hNlaHAVuWpcCdc01+eQYV8mr/TukoMwf4A/vHRnmCesDK8Fm+hmfk3eE7py\nXTn8fFwRnVc+lFACIwS8sQiMqmP8LwVbdLHfuLqqN/lYkXX4XRVj7+WfMs/pCXZaQ8W3R6Ozm336\nafZ6xlRd9ubCr/6f6nmF4l1W50CTL5hXlBeb9/nKooq6Wl/bgmgsr8Ts9zZ9aVWBRT4H+kD8UNir\nWi+ohDvw9hjCZbON7Dkme9+eRSRW8khOGkYDb/P1gllFY4wqqZqlWqy6X/WoimszBgSTl1M0UAKF\nL/CxvAAUjHSWx0cvVcTlzf3cHQnV+o3yHk2Cl/8RlT8XtslmbHPCpZscdMdGAc+GBv+EcOBKgEiR\nlyd6RJQHT+OViTs+J34olzfyS/FDZuLlaYXHJC3mW8Qjh+IoDMkEJjkZE281HdZczhzWSKKGljca\nYri6TAHhM/TcamLGQuhD+Yll4h5G5/xch8WZmSgHLZbux0JSVGkoDAaD9hGLMFP7nDnt984SP7zn\nno3j6riG4l5KazCVPcqyrFyXiddpkXifuEZ8QhwtfcwmFF+UQb/mj6OVaTbUFNkWCwteR4Y6MpnQ\nC3VNm1UebFHej7W3mpG2p6Fw6KQmPTfrXtSQC/Ee8Fr2igbhLTnu2R6Visn7Ppqh6/iAQ/xPNE/q\nFg0HcObIb3ar7vvfM8fPcuaoUt3ozHHkHJejQbVcMPCVwkKsagWM/0mb/KI3auWdlEHtWW0OH3a1\nFjgvGLGGTQv5lnxxBb8z//78R/M35j+Xn8o/lD+YfzY/B83CwTuPGWt3HNTl4P2PofEIjLl+vtjl\nKsa/Q5kLVdTu8djH/EP8VpVLGFHd/InxW1Wu6H811uvIOXGYP/9jgklwCnt0DBuPOoUkC/GkeAOQ\nVa2ILHRmUM+eNGm2ulYX9/vjOtVjrV1drQH+P9nn9VfCKdW3/9fn9f+XPq+qjhv7vIojx/g4Oovm\nFp3w7ZQ2RGM9kQ2l4eMjwkwtfVZ8T6G6yEwwY2edT5hs5A3Kgfs0azRPaOhXmpmaRZr7NPxXaoWq\njf9Kl9lyHNSd1dEUpcaUqHCkyL5FCHYuD5Ya/u+HfL4a3pO4E5PWRj4fCF3isPAPqjt4G22gPdkB\nkCi9LKhGGZSUXj4g93oVSsnJ9J4x3bYr21vrM71U5k52C3tHfnL98Zz2w/UKxQhoNZbz8fz8Afxu\nsThROCe+y39n38NUKvmsBDGXBZG4K/mq5nsY/N89IHPkmDl8XTzG79cK5WNCJl9z5K1BJ46wCF/Q\nlJtZ4VTmGf7+L9hR8djHTeLjHx/4fzYvJoR4Xv8o/lioF97YY9F41DV7nJpCjiGNwLFKo1XXpGFY\nIC5MFuVoC7U4LIfmu1z7kBbmB7u0B7Svak38W63FafFbopbJll7LEstKy1rLJst2CziBEQrLco6v\nx2GQ5BqETWKYMKLI2ccr7LsmZNJYipCUz9JvEK+kTxsuGlAVvaHAEDRkWPZXG9Ybthh2GvYbjhlM\nGK/g75AK8YU7b1rljZmzcVltcTlg9Z5x2FPOVR0RB5MmdIVcgc7bGhtv6wy4Ql0T/nQ4NCXijvQ9\n0Nb2l/Mi7oYp4cN79VWTZkyILmjzVbYtaKydOalatzd+iyk6pS/ccf/sCRNm398enj8larol/r+y\n/X9Vtv8bv/y/Hr+8bOQjMZ/LrFD4CsyHi2Bc3K/nMnIrhHMQmCwOM39O8zV7Ulk6H3wwW/pz4J4y\niDWodVAOTtvvFK8kixDEOeCMObud85xLnauc65ybnTuc+5xHnby5nnSeB9lAgcpMekClNuOLIlsk\nObz0wDGHmG8tyS8pN/P5ZzL79XRDkd1p0OfYyqtdrHp4KduaSAy/5izLzcQwGPkt28b7WrlQI/w8\nVRtCLIJaouHkarjsimIbgpemiz9vNl6PzdJfobmSfrPiUgV1worCiqqK5oopFfMrllc8VLGhAgwB\nByperTCRpUtwUKrS2KyZmL/jPBdo7U9kRiL2cfuLSRDFruJAcay4u3he8dLiVcXrijcX7yjeV3y0\nGIIoPl9MKj1ifqZPV16spN5XWVAZrGyq7Knsq1xWubpyfeWWyp2V+yuPVZoWSlWUN4QGc4dGnTcQ\ns8r+T2RFqXj3RFwqeUXhiEbZtkR3rCcuunvt3lBReNK8uXlOt8k+wSUWTCt1ufxN8apYa9tfTKqc\ny1TVbRNcnS1Tn+3d5K6w6fPtXtHrDzW1/Kztr2UZ145cFutFl1AkVAgFUnEF12IqsPZUmFg9FTTz\nOa4iu5MHgkAjdH7HM4ne1tv8XlcolgwkFnX6fJ2LEvFFnf4VrXPntjDV3kRzq8MXKTfXTLsjHr9z\nak3VlDtv8n29peXriHtTJSwTX2RfEwJCTJgibE5NDaWmkQIw1SJHa0b/D+J9Bi8F6X0GC4NVwebg\nlOD84PIgoo1uDe4KHgi+GjSR+Vi7hr8jbbuz3d8ebZ/c3tu+pH1l+9r2Te3b2wfaj7RjbG0/1y4u\nFPY0iho+ZHvFGj7Ra8jOyauE80rVWFI3DaZuIv7kLj4mVma8ca4iJpV9dXRy/HddKf8Urcz6mKOH\niy/afRPLSibW1dic1RMipWWRSrvNFykraQzV2O1VSJnotzdXVzmqAl6zxRuocvmrh4+bfVXVDlup\n3VAbtFcHvVc80aDL5vHb8v0euzPQ6IHjg6M8YLMFyx3OQLTCH7UVl5vySt2WhkqTp9hmLizL9zdY\n3R45DtbI+3yB8GMu42amTsVDqQRJOE6m+7kkYQck7LjkIAk7Ch1VjmbHFMd8x3LHQ44Njq2OXY4D\njlcdXMJ8RMjnnc/SHyY5h51hfzganhzuDS8JYztoU3h7eCB8JAw5h8+FeV8gJRYKWHAwFQwJ/N+1\nFKfkf8072h4z3oaUryGaynLig0ifdl90Uy9yF7iD7iZ3j1v2Hlzv3uLe6d7vPuY2Ybe+v5F6Z6Or\nMdAYa+xunNe4tHFV47rGzY07Gvc1Hm1E72w830jGB+MW5E7XxKvsstQZx8OMW9ZRS3h+T2hqpMjd\n0FNX3+th1qquid6I21c2uSY8NVrpzO0qmhWuiHitVm+koibus7C7Y3+9YnrlpNm1NTPiFXV+k9tU\nveiWqNteU1zqiXbPmvMFX8xdG/eUttSXhnvm0Fh+50gN26TKFxoEB19b+NU1wp4y0cHbaJ2oV9eg\n2jSsomZOp8MqG1eT1zyNEdGJjXzk8Mttkm1yWPK4tq0z5ulUjInOhrAjYMsz8SStKU/DRJWhaILX\nUOgwiWetVqPZ5A7U1ZRphvVl829pdhbm5RvzjBOaI1oHu+xqaW0Jl2iMNuiqH45Usw94HfXYwdcJ\nGB00XpUuELPZIszX/t26gjuefan1JJvLCxxOq57EcxWOVIvt/DcGwUFcd/rQnhwRyyWNqMVzuRoZ\na4TVEit3FLIpw4dF8/Bk1ji8n50+GWOH2IGmScM3D0++CXl187z+iuelE7w8H64VcK2ECPX0il8/\nDqCFPVqRIWeNtZzPQOVWsXV4arsYP6nafaVXdeFKQYbj8qfst+I7gkbIEUKSBpaQWpEmeT39kSOq\nCDBK4t8IavqG/tBD2yI2lcpmY92tu3a1/sPx9es3eNk6tm74IdY1/P3h77Mu+BlRQeKP+Ejn5f2v\nRmgYncf8gyl/qN+pvoKJrHKov1jFK65iPi6YShFrSrX8ELHGiCMQmBiLRmNYmY3a2dMEwf9zuPgj\nMv7vZ02NoknntFrsueoJHs8EbYNuajQ6udDPJ+SXh+9gPxoWHuzoeNDaVGgqsZpdNmuOr742ou9p\n624pa/SW2+wT94vLP94sPv1xA68ytclbRi6IPaJGsAm9kk3N5aBTY7KEtqcflEzyBxv2rCRr9oOD\nr1ONoT1Wesm5oo4PsGRKhA0DPnvLQSN1GHL50MrbjhzivjzmUsLbs6rpEyd9a2/nH5n75omtTx3s\nGlm9sejBlsdavlm8iiNE2i3ME+eybwilwk3C7XvyNGZ1jRJKz2xJ1Q0Ke5pFCNIuGjhGxGqOboz3\nROZHHPnXbLSlIrQR7wnxxbMckw8pLYOpFuzBjd3p8o7bA3Pc+CtxrspaWlNaNs1f2VVUEdRM4B9r\nS8unVPq7Snw+XQ19LJtWqXyrtpTgW3/l5BKvT1fLvuFu8LtceXnOeo+7IVDgzMtz1ZXt5pfZxKCS\nSM3sFkHL35Wfa5C5gl/S6Plcrs8YCIqEuYTGIWGPHm+Fz+yNlQ6NxqHh3e8W9sHwQvad4Vz2AQu2\nvdT2zN+1LUkkrs53gpSTzVcS9WQ6o6d3m0PvNmdc9rHGyspGjYNR9t8dvo0XwbO/p+3vnuEFDP8M\n2fMxZf7IWTaTfPFyBHiHIqijl7nYDnIIGvXv+f88HkWWX+BmmV+AjzrvCmfG8A48lk2/jHQuK2Ek\nIL4oviKU8f4+g8JEY36z8fnNlpnsyNr2upoI+TRgGqxgZkyDKhvFu6Q/fMjJBJnmA0E0FijXeVmE\nedH/5V0mVq4SX8yGnLYYjTOGN82YyyZOZhO95fl2Cj89bGeRraMxqC3GnIMHxVc+bikvLKZY1GwD\ne0CJO/ZrcYdqPX/rufR8b7Pm66ZfYN7rpl9khWPS78im/5aVU3ovF9Zeut8o3y+cJfmZkM7lZxHK\n2VekonJogTBWXlMus1iDAOWQYuKsVRG7rInMJ/LAjA67hnIKLLsIrn7bAIJ3XNC/zFso4x/KsKHC\n2BVowAZ2RTI5y+SzvH6LCC0Th3J2OogrVLEVclSyFdJTOJl4C/A9QFP2jO6AWjG0UVgoFQ9x6QCO\nZclufJ9iwbZQ2gp4C/A9AMWBJTcrCtjqB+cqRQ1cB02zF8rteYAfp8XrcNULj4h9UHgPeck5BHWZ\nnA2A0YW6bAI0oXSKAjUVsDtLvjoVQFGfDqD0uSh9CnmJoWDyXO8GfI6XFBv134J9sZeP2Nasm7r3\n2b+dvWqm3z9z1ey/ZeLwcM+UKe+0P353e/vdj7e/014/e2kstnR2/W+44hKpnf943/wvz6+lNrCY\nv2svtQGT0gZ+MCb95mz6u8KxMemPZdMvC8fHpN+RTf+t8B80XizmfbGTt6VKYd6eAjVmiAIY22R7\n5Thdb1yvzJwD73EwJ/8ZV+fyGTEfFfA/hYNSpcpynS5Zbi130H/875h+KXaO6ZSG4TVs3/DX2bzh\nXewRS6ZbjumRhlzxlfbftA//rj3TJ7P96B9JVnal35WPSX8sm36ZVYxJvyOb/lsWUtLd4j+KJ7Pp\nv2OerAz/gvJ3yPlzKaI/UjqXITimHuQSgwWSRZlC+xlfu2BKH+pXqzNcJTm0E2yk67zBqziIx/Nq\nZ6zyMlLPGH3uUYkmPl8bGa16bQotCJZymEgW97DHenqGv9TDjg9/SXzl+ec/bmEzh/vZ12+5ZWRk\n5Jf8xQdU9/HncPL6a4V3TBRHceQKT8+lNiWnv2uQ4yvewv/sJznJ6b81yese20hAOMqfu0SI78lH\n2/kMrYbsDbFdUKI0D9e45uG18qcYbRZHx7YKdU/+DdrC6NhM9c0b+TX7E72nIuU9/Vp+f/y9Pkw2\nNsXyexX2Zd4r+y3dX0LP93aDMJpO95fQ/ZeEXZl8xqX/Tvj2de9fKnw8olHazW7Kv0yZJ9zZ9jQ2\n/SIzZ+u5m/IpU/L/ONNeVfn0firkPs+qx6Q/lk2/zIJj0tdn03/DEtly45ReK9dH2H/d9IvCP2Xr\nE6f61Cr1+QdKb+By/ojun6Dkc+i66ReEPdReGkYC7CPxpDBb+GXqllBqTih1i0KcmJpjSU0bktjE\naZjMS+lPaqKlv1MFBbrT2envjHZO7uztXNK5snNt56bO7Z3w9IYC3XmukyvQ8rbWNEt/jYor6TWX\nakhJrymsqapprplSM79mec1DNRtqttbsqjlQ82oNV4Zp70Lues28TTbz1soX40a+pPAX8gmVFRLT\nY6GlXy1ekUrlT82W/lbGle3Wi62kbLcWtAZbm1p7Wvtal7Wubl3fuqV1Z+v+1mOtJq5Aa1yK/gEV\nVDYBzWrQMb4UHuPxqx0l81FUajVXW6C3MIOotxpKQ47yKvvECZaKoDOozrWb85y5+fXNE+NVba5b\nmoqiNcWeSFtXW8QTaLulpuXz1a2hBcXRGnd01qJZ0aqO6uKSFqZSB3yuCkdugS/fXqjOM+VoNdYO\n0VHYFAqErOVhT2V9udNZXNNWH5neUOAP13eZPfXl4caKoglTk+GbJ+blqATl3brxDrPv9nfCJrnP\n8bYTpnceUtrODqUvusUwtZ2Qcv/mG6cr/iVhiuk5Y4+oVvxLdETJb1JGShoCr95+3GOGIoVFjprU\nGy1UqH49n4r4MGvC+kTeZ4000l6rIyKWvtXz1lvvihXvvsW+OXwv+2bLnvb2PVS3uXxeWEDjYz3V\n7R3egkfTb86mvyv8fEz6Y9n0y+PSv51Nf0/45Zj09dn03wh/pGefy+fiBfzZY8KzqaYQb5appow3\nfjMFSTTZArL2SBpxwNLv4yu9GCVmh95xVn5EK5P5YOQfjJlxmEy68MFo6S9h2BQqcZUESsYe2G4u\n2VGyr+RoCTaFSs7Dqimmsl8zpfOmjF1seKCpeXNW0yW13TGr7pdGx3FV54SGuKPHXl5V5c8zBaqq\nyu09jnjEH3WarhnbVaqC4rm317IXh6dHpjSUWDQaS0nDlAhLD3fW3j632K4pyM8M+4q+oUqRXGPK\n/P9/aF7js7Q4ndKblfFIbpsunu6g9BZl/Hp6TPod2fTfCk9m4gyzfxa/xtMn0Tzx5JeEMemvZNPn\nfEne0gjz8e4X7CzXvmcwdWpmKDUrlKobws67vEUo2eqIQ3CmJVU0iGOJOksqMpiKhLBw71Bj6Otw\ndvg7oh2TO3o7lnSs7FjbsaljeweYMDD0dZzrEImW4ebR9VoVf69VudebeRv4h4arz8D2lImT+JBn\nUxF1ShVvUdhM9F300fjmK/AFfU2+Hl+fb5lvtW+9b4tvp2+/75jPtFC6Sf4J1wp6aE+xx9UT6In1\ndPfM61nas6pnXc/mnh09+3qO9qD59JzvwZ7i+KWgFw6MmRQ+/kUaJ3ordAHZ6RMWcmMWAqqxtpeN\n7Bdj1wVMpRJLZjZ74hOKEvPvrC5ffctNwfYvV7TWFWtUpsyK4YuF07rqbWUBu6/RZx23fLAGbaEq\nbEk2t5XpjQ/FQp32qkk1Py5K2LIK30qNLeh1lTtyCqpinsza8XfsJ/TOe6mNtAl7rpv+OWWuvDp9\nntIGr05fKnyH0oMj74s/Fd/n6YvltYcoUptC+mzxfT6jR1lBKhbCQCEOEfEYbe2lYhlv5AmZjfoJ\nmeY1QXFLxmBahlESQeZ5I/M6vX5v1DvZ2+td4l3pXevd5N3uRQRoNDLvOW+GAdTDG40nQ15G40zu\nVaPw+CVqBYZkSZML3g7JTX8wQPPKVNB2Eh+gg9R2gq5gIBgLdgfnBZcGVwXBI7wjuC94NIi2Ezwf\nlKnBG9A0Gy42UNNsKGgINjQ19DT0NSxrWN2wvmFLw86G/Q3HGjD1YqxvvDZAWob17SqKSXF29Lph\n0o4ebY8Oe66OqSaGPx68JiL17okbNw6vvYpYLDs2XKH3u1x57/8wJv1r2fQnhb+/7v1zsu1kfPpS\nrEWVMeYKH2NiQlL4ZqotBK6ftsyxULsFHuZ59lJI3i5zupda+pv4HzpokGLyV2WWVHIwlQxlR5EM\nMd+eJtHDX2GeqhCvMEZ/sCZK4FUkLiboVSQKEsFEU6In0ZdYllidWJ/YktiZ2J84ljBd0+Vprsgc\njTnK6TAo5ho/WdjkkyIHWzvayTWaCcHaZKUv2dvQOLe5dPhhVXFdi7fxZnukOuLxui1yH2+b1VPW\nMqFoTO/WqEWLTXlP/tZbw6XeSRPc9WXVja48TbFT6d1/1zGnsDpakhnLLaKL5PxFpf8OXDd9jnDw\nuulLhe+PSX83m/6+sF32YeYT/WkVYtU/ruT/93w+YtjhYad5vy4T+lPlIRBglVtSBYOpghCd3DIy\nyVYN4gVVYPuw38RTuapePCizDYyhrcr00HH+FeMmfxf/4JJHf/RQlbFE3qLst+K9Wi9a6b1aC6xB\na5O1x9pnXWZdbV1v3WLdad1vPWY1kXkwH1zK0JnR3eR4M04HX2Ipb8/hzZIsTvuXrCt6dAo5ore0\ntP+LGNouu6IPv8FUM+aQI7oYaty4UdZFT3F5FIuQ0zKaU38sCpm5nAnUb+T0J5k81+q5LvqiuJ9r\nXlXCQ3tKVT7YmPgu0TyW4yv0VfkQSXG+b7nvId8G31bfLt8B36uYx8w+6gLmUH8+l6hPCYMgpAKh\nccrsdafUMcps4NOVWdWYfdSxe5AGsT0vM02x0vz8UvwbN0Wx14drM5ORyuEoKsI/0sFHfj5iEbay\n1wWbMH2PUZMDHTw7BueO3T/VT5oPVYaPtmqXOqDOGLeuUq9Tb1bvUO9TH1VjtFWfV2Om1rkU5QSr\nOVJgnCq9TV9QkqduF12xicUF/8hEdX5JhVX0f/xabn2DP1d+P7w+XGfh/YF9jt7P54YFxXffzX5J\n89nXKP13C+X0efwhnKqdPP0JZR4tFn6lpM+k+5+g+y89IN/vHnEL28ak/+7SaD438f6TyWep8I2R\nHJ7eQf0K/XOLkv8/0v1Xp88TnpLTeT1Ps7PZ9N8JX6X0/HH38/q8mF37ieXUHp9WxvH+MemvZNPn\n3CB9rfAmpVOcKUo/RPm3zZDzt/P63Er1kdN/9ys5vfSq++cl5PRxsRGQz6rrp39ukbyHU87nD8QI\nuUW4CIV8Lqnisk4+15KaDp18Osw6atSfUa8mfzDo7l20tuhydvm7ol2Tu3q7lnSt7Frbtalre9dA\n15EurC26znXxqZ2WK1zpRzlZq4IxmnnuZ9PMkxi7kheTNHYlC5LBZFOyJ9mXXJZcnVyf3JLcmdyf\nPJbEnOT6zJr5uIAWuquCX5CS86Mb6ueN4aq6G8S7SIyPjFFuy7++gt6jsjpuEAcjcHXEDL1alN+z\nG+8z+55/N1dQ9O332YP0/n+o7GU9ldHDwf+rpPP7m4Qbp4/hC64Qntuj1WDjV0sewE4iZ3TSClOL\n5aWAQ8LsnDQu9GbuVec6e1SiWi3H+MWRAlnl8XHK4DIEDDFDt2GeYalhlWGdYbNhh2Gf4agB45Th\nPEip86we5aDVRY4XhYPKArNYmZa4pj+e+rdR3gLI0P/+5V+OJwCeMUOmAF7S+NBYDuC/bVwCEuAs\nB8n3ZA4SLscfg4Mkm/61bPqTinzHcZbQOPD0mPSL2fR/FbZm0sX8MfevFU4KModNgI3wcb5ZGFCs\nU2qGaMaSz2fjyhq/vxTKJdmR1OCMN1UXwkeK4pNd3Y3jHb6xwkhBfTIfMqaBXFUE+XC/l16RF1Gr\nYt5u7zzvUu8q7zrvZu8O7z7vUWgOJ73nQa7YTPdfV/e7AXnN2OO6kXHz5PVJba5/QvAJVDfZzWJl\n3+oVkveQsh77jTDqY634YGO8VMbRcX6aGF8/f/30pcr8thh7PeIrgrx3rhOKhB8p79nC79/P09dT\n+leFd+g9+4XXWIBZYQsBbY4NUUjKIUGOt90KzySK5XBWhGNoJXxKA8MjjL3WLq+DAP/EyxOFXPYX\ne7RqDR82x3kxbcN5VyuM/VtxZcbVGbUc+AFG3FjoF4D/Y59wFJ63CE8vG7bL7BphBRZKg4CNYLfR\ng+pFJDrUi/BQ3s+OwUPZBb+CHL2okGgslHJyFG4HKVdFqX+Ab3AUoIXTQRm4ZFPwyHwNAKcMaRvA\njC/uU9JWSGdxNQvwqDFjyEqnJFeHg8YRuOyjKIl0lf6++AMEuxwS/xOsWn8HUd4lypHU9Rg8Ml6w\nq+B+NR9UBb3w9V3GVuOJdoHaZYpmPuhJQGeWnqzthddvN4QC1utYuYrRkXOg/CUW2Tr8sXy2PHfG\n8KYr7IGPN+Ks4qDynlQPkT+VjU0FqaZAMdbNQ/15XJhfAJ/LixwGvpL3VN7uPNUKSZVngMRA+C8z\nJRyE31Yu4DwdZsKlC4R6IoWRBCGdmrLMGZJeUPiGFkpn4Lm7JueJLN+EGbwm2iHJJGd/0ARud0vK\nMpQ0g452jeUJyzbLC5aXLboVSVvcMtWywHKX5WHLVyxPWXZbDlpyFqbftFyCGXaORdnUegHMXmYH\n2AZmOhY57nOscTzh0Cy8Dq1/lsBEsOYqnqRW+RRRHBy4W3xE/BswE8bxjo4T/Zl8mybUr+X35BI/\nNl6ZkT5RjHlm9aoq5dNF3jV0XnhesxHD71kPsw//J2sYXjt88tFb2b+z54bfZHr28PDaDThGPHJE\nfIU6ENhwKpIC0+wpEITc3AZBLYRGXuQYHfkRx9jInzg2jwxwjBMmCF8a2c3xrZFfcxwi/BnhGcKz\nQBZFPixG2ESYRG6sDTmwh+meRzhqqEQNlaihEjVUooZK1FCJGipRQyVqqEQNlaihEjVUooZK1FCJ\nGipRQyVqqEQNlaihErVUopZK1FKJWipRSyVqqUQtlailErVUopZK1FKJWipRSyVqqUQtlailErVU\nopZK1FKJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQ9\nlainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUok1Qj7zKUUOo\nJdQR6gkXjqzhmCI8jhRmIDQSmggf41jCa/5djlHCGKU0jzyLU1fCBOFLhD8beYvjGcKzQEa/4rUF\nNhEmkQOvLb+f1/MtoZrXc4CjhlBLqCPUEy4cWcoxRXgcKbyeQCOhifAxjrVCiLeDWiFKGBMsHJtH\nfscxTpgg/JlQwPEM4Vkgo/tZjLCJMInf8hry+9kj/J4Qr+GLHDWEWkIdoZ5w0sjXObYSJgnbCTsJ\nJxNOI+wl7CO8jXAh4XLCuwjvJryH8F7CdfwdhYT1I3/k+DSlPEP4LOE2wm8T7iZMER7i0g4J/0bX\nrxAeITxOdT5B354kfIPwFOFpwiG682eEZwjPArnk+W+55IEmQnpG1kVIT8q6CXsIpxBOJbyZcAbh\nTMJZhLMJF+Dp2BK6Xkq4jHA56sPuIrybkCTDSDLszwnvI3yAvn2QcCXhKsLVhA8RPkx3PkK4hkp8\njD9FlHpKlHpKlHpKlHpKlHpKlL9fYCthkrCdsJNwMuE0wtt4O4xSz4ryd4qUuwjvJryH8F7CdYTw\nt47yd4rrZwifJdxG+G3C3YQpyvMQ7y9R/h5RynFKP0EpJwnfIDxFeJoQo0eURo8ojR5R6uNR6uNR\n6uNRRk/B3yCQnoW/KeAMwpmEswhnEy5AnfmbwvVSwmWEy1Eif1PAuwkfIHyQcCXhKsLVhA8RPkK1\nWkN5YrSJ8Xfxa44aQi2hjlBPOIn/KsbfBTBJ2E7YSTiZcBrhbXT/Qi6rGH8XuL6L8G7CewjvJVzP\n+3iMvwVcP0P4LOE2wm8T7iZMUW6H6PoI4XHCE4QnCd8gPEV4GshlDjQSmgiptlzmQKozlznSZxDO\nJJxFOJtwAWrIZY7rpYTLCOm5GD0Xo+fiMgc+SLiScBXhasKHCNdQbo/x62Yae5tp7G2msbeZxt5m\nGnububS/y7GVMEnYTthJOJlwGuFthAtHHue4nK7vIryb8B7CewnX8d7XTKNZM5c5Up4hfJZwG+G3\nCXcT/gPVJDXyDMe9lHKE8DilnyA8SfgG4SnC04Rv8RbVTPNFM80XzTRfNDOqP5c/kJ6Cyx84g3Am\n4SzC2YQYnZq5/HG9lHAZ4QOU24OEKwlXEa4mfIhwDf0WM1ScpB0nacdJ2nGSdpykHSdpx0nacZJ2\nnKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpyk\nHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0n\nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGkn\nSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0ja\nCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmS\ndoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaa8UMNqsFF4S8oUXhRdHhvjVS4RYgbxEK5CXhB/y\ne16iGfwlmsFfohn8JZrBX2L307crCP+C4yG+XgL2ES7ktTqE/QyOywnvIryb8B7Cewm/SIgZ9pDw\nTV6fQ8IWwqcIn6ZvnyF8lnAb4bcJdxOmqKy9uObrGWAP4RTCqYTTCG8mnEE4k3AW4WzCWwjnEM4l\nvJXw86gJu53wDsI7CZfQt0sJMcIfJ63hOGkNx0lrOE5aw3HSGo6T1nCctIbjpDUcJ63hOM37x2ne\nP07z/nHSGo6T1nCctIbjpDUcJ63hOGkNx2kufotmzLdophvi169yTHH8Gcn/ZySZM3R9hq7P0vVZ\nXDMDasuR15Yjry1HXluOccIEIa8tR15bjkOEPyM8Q3gWiNpyjBE2ESaRG2rL8WG6h9eWGalEI5Vo\npBKNVKKRSjRSiUYq0UglGqlEI5VopBKNVKKRSjRSiUYq0UglGqlEI5VopBJNVKKJSjRRiSYq0UQl\nmqhEE5VoohJNVKKJSjRRiSYq0UQlmqhEE5VoohJNVKKJSjRRiZXQvzhGCbn+xZHrXxzjhAnClwi5\n/sXxDOFZIKNfQf/i2ESYRA7Qvzhy/Yv5KX8/5e+n/P2Uv5/y91P+fsrfT/n7KX8/5e+n/P2Uv5/y\n91P+fsrfT/kHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKf8g5R+k\n/IOUf5DyD1L+Qco/SPkHKf8g5R+k/IOUf5DyD1L+Qco/SPmHoPNxjBJyvZIj1ys5xgkThFyv5HiG\n8CyQ0f3QKzk2ESbxW+iVHLleycKUc5hyDlPOYco5TDmHKecw5RymnMOUc5hyDlPOYco5TDmHKecw\n5VxPOddTzvWUcz3lXE8511PO9ZRzPeVcTznXU871lHM95VxPOddTzvWUM3SlFxl0JaCWUEeoJ+S6\nMIOuBEwSthN2Ek4mnEbYS9hHeBvhQsLlhHcR3k14D+G9hFwX5shnWAa9CSnPED5LuI3w24S7CVOE\nXBfm+G90/cr/7e1MgOwo7jPerZV2Vxe3AWMsP+MDDEKWhGBmxGGt7gvd4pAlpKe3o92Zefve8o6V\nVoBlrxHIB5CkcscCh5CkApWEHChEoOC4HBIUJakk5iocQ27HSZzEOSqpOFH+329mtU+ywJWqVLx+\n3+s309PT/f96ju7+PgG+CB6nzi+z9xXwVfA18HXwa+T8Ovgm+JZQY2GvkZRwJkgbNRb2GkkJV4Ar\nwVXgavBWcB24HtwAbgS3qXUaC3uNsISDYKL6aCzsNcISEhlPZPQkNayDLfa2wRFwL7gPHAX3k/Me\n8ABntLGwD+A3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8A\nfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4\nDeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3\ngN8AfgP4DeA3gN8AfgP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8Q\nfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4\nDeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3\nhN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8I\nfiP4jeA3gt8IfiP4jeA3gl9G9z6C3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC\n3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4JfZAB/BbwS/EfxG8BvB\nbwS/EfxG8BvBbwS/EfxG8BvBbwS/EfxG8BvBbwS/zCH4CH4XaX7McArYDfaAveAt9saySPNjhovA\nxeBScDm4BtxOfnvbN0xIp2AGVsEh8JA99xdp3GR4GHwUfAx8HHwSfJrSvkT6RfA4+DL4Cvgq+Br4\nulDzY4YzwJkgtdX8mCF11jjLcB24HtwAbgS3qYYaPRkOgIMg7fK0y9MuzY8ZtsERcC+4DxwFD1Da\nmKX7NIdgOAXsBnvAXvAWY6pPcwiGi8DF4FJwObgG3A7uOHnQMCGdghlYBYfAB43xPq6gPs0hGB4G\nHwUfAx8HnwSfoiZPnzxs+AxbXgSPs/1l8BXwVfA18HXwDXvX7dMcguEMcCZI/TWHYEgrNIdguA5c\nD24AN4K6Ivo0h2A4AA6CLUprgyPgXnAfOAoe4NgxS69xa12/YQscccsND5I+5LYZPgQ+zJZHwCPg\ns26+4VF3k+Fz4PPkPAa+AJ5wG/waf5vyW2+xLX4H6bvAneAusAwOk/9usAEesKN2Wg03GLbsLDut\nhlcZHmTLIfAh8GHwEfAIOZ91FxketXrutBoKn2f7MfAF8ISb5XdaDe0oq6FwB3gXuBPcBZbBYfLf\nDTbAA7Y90ZyJ4R2gjc0Nd5FOwBTMwCo4BN4HPmj9IdGcieGPgj8OfoG9h8FHwcfAx8Enwac51zNK\na87EcCW4ClwNrgHXgreC68D14AZwI7gJ3AxuAbeCu1UfzZwY9oMxuIe9A6Cu/ZQ4pMQhJQ4pcUiJ\nQ0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxSIlDShxS4pASh5Q4pMQhJQ4pcUiJ\nQ0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\nQ0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHjDhkxCEjDhlxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\nQ0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHYbtyZxm2wIPgIfAh8GHwEfCI0K5E4TZwB3gXuBPc\nBZbBA4b7NVdm+LThPcT5HiIwxnzRGPNFY8wXjTFfNMZ80RjzRWPMF40xXzTGfNEY80VjzBeNMV80\nxnzRGPNFY8wXjTFfNMZ80RjzRWPM4Dl3ib8s/68qGU7PNSVos3rsV57uciV3QZGe3JFniuWZX6S7\nbXtUpKUnXFqkLyB/l/OTp9r3Z/XfWCHt3cXGRp6e5M7x+4p0l1vkHyjSkzvyTLE8Lxbpbtv+1SLd\n46/y3yzSve6yrguK9FQ3q2t2kZ7W/Uddq4v0dDdn2uVFeoZbPW18+3luxrQfLNLnu95pX+wbiWtJ\no7S4Xs82xQPtarnRseXGUjhnbv918bwbS/Pnzpt/7dwF9v9iU57tWmUrjkiapXKp1Sj3x0PlRlaq\n7ymtjJP+uLo7bgzEjdLSRruSDZWblcGkFtdKfStml+J9lWq7mYzE1dFSNanEtWbcX2oNNurtgcHS\n2qRWb40Ox6UVQ7tXzi6Va/2lofJoaXdcasQDSbMVNyxzUitV4karbN9pu5E0+5NKK6nXmnPcEld3\nw27UNVziBtyg9fGfM37nu7lOs0ol6/mJq1meluUZdrFtWeGG3G630s229F7+5rjqGbnmuIr9GrLv\nkrM3FPsrdZyhya/YvmP7HjHst5x9pGqWq2H7F9vxdZe5TbZtwLWthLJtP3ueGy0dWglzrZzrbP88\ntqgN8wyvte8FBZ6eq7O0a0+Vdvo5Empbtk/Lftvz3fYNUZfMttXdHsOVti1hT9UiozYNgCXr9w2r\ne8Xy6pimpQaJlMpXZFYQxdjtsz1Vy9m0vSOUM2rbFdUKeZvESHUYtBLrllOR/F7slG2fjtK5Vd5u\ncjSIqNrVopZ5yQk1qrClZfnz36mdqUHefurSMqxTnznvcO4+y62jypSxnBi0YD+Gw3faWyKOTX7X\nirqdyYiOm2f3l9D+8nbuKdpSsrrEsNM8xc6g/R7hqIEiJnkZ461XHMZLbbK/SSqmlnuIet7CPba3\nwhHq16s44szydKbYrgldGwl8fTdLs6lVXJwvoY357z1w3zpVbt3iWSUW5VOxV33qZ8Qp76HVom+V\nicREW5LiqPwc4/046Sgxj9Qy27O7OHq87yyHnTbHzKYPtalfXoeynbNJSn0so/w2sRsvc/ys6uPD\nRUzFZYWt42dpEptq0SvV0/L25deC7lBDHNXq4HWiPXuLfSo5j3il2KJ6j8LWliL3Xju6cZZeNUTc\n8nhdaeWPtzq2X+MRXM7vGlfxRN0HC/abRZ3KRXzGa3d631Ht98JcicgNdcQqKUqZ6E3DnLF1FvY7\neZnDvTDnpW15FMecizPZO9u9Le+ZJTtX3t783qOrMa9dC84q3FMTcg5yLytRVqPgq8w9vknuOmc/\nPR5lys63JNwR8+s1z9HZPwdhKHH7aW+r6GPj97OSu8K2X3Fa2ae3o0xbVLqupgrbKrRY99j4tDtj\nszhbi6jkd5v8Ph2TI+ZOMtF/8p5ds0iViz6cPx2Sjntotbi/7rZPlYiNdpxxoLjDn8lFuYhrw2Je\nZ2udK6mzrvmTIOGekF89w7S0DL/j19QeWqQrtV5cDS2uvtZppQ1yXP+pe0bnPS1/+i+gju98rx4v\n7czeXuL+0ijin9cn7+Nv/9TQ2TKOUizWcO/Tc6sMS4nLn1z59Zt1PA/PFsu8VhWOKNP+t8+9rojO\nROTG823graNFjdtWyxJvS1WiP/EsnMM7Tctas9Bpve97vRP973J/lFrpOjj9uah+2dmO8beXQp/v\n3Mln3Hx3lv/5++0zyXJ1ud+2CP+8necX3Ifch638K91VVt7vuOPud93fuI+4q901drWccL/nft/9\ngb0hzbHa/BlvVXusbP0jwn9otflj9/3uF+2NaoG73t3g/sLeGv/enstfdS9bS1+xp/RCu3Pc5P7W\nPedudn9lb0S6Nz1k7f2ivV1Mtdr3WYxnug9YW5e5j7md7i63y93iFrk33Dfcg9bn/tTa9XV3v40V\n3uvOdZ9zx6zHjLkvu0/buOtZqavdq9Z7honI3e497in3K+6Xjatv2ojhp6xHf8ld6n7T/Yy7xD3v\nVrvPGIfvt3fcJ91vuBesl71p7/prLbojxkLb3Wq9Yb17n3vC/bnb4LvcP7gfcf/oNrrLrYd027vo\nqLvH3et+yb1ld6eL3L+4f3X/5A67R91PuvvcZhsTTrdRRK873092L7pzbOy7xe5Uj9to5bfcr7pn\nbGz4a+4rbprbaiOfP3G3ub90D7hZ7jL3bhsXvWTjytvdt9zF7t/cP7vX3efdu9y33R3uE+6T7lPu\ngPF7p9vmPu62u79zR90Pux3ur92Fforv9j2+10/10/x0P8PP9Of4c/15/nx/gb/QX+Tf5S92j/lL\n/KXuJ/y7bWT3AzYS/4L7afdjNhb/df8eG7P+rI3Ofshf7t/rZ/n3+ZL7L/9+d9Jf4T/gP+g/5D/s\nr7QR1Uf81e7f/TV+tr/Wz/Ef9XP9PD/fX+cX+Ov9DT7woY/8Qn+jv8nf7G/xH/OLfJ9f7Je4//RL\n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\n0ALYRzoAqQCkAZACQOv/B6ys2f+vd9C1/wd3UY3cZ2lVVmuyWpHVeqxWY7UWy0qs1mG1Cqs1WK3A\nav1Vq69l2jyL+/BLeBQm0WrV+EJ8E3JNyDMhx4T8EnJLyCshp4R8Ep1PSa2uam1VK6taV9WqqtZU\n8xXV/J1Kf+5/AIGHtqIKZW5kc3RyZWFtCmVuZG9iagoyMCAwIG9iago3MDc0OQplbmRvYmoKMTkg\nMCBvYmoKMTI3MzQwCmVuZG9iagoxNSAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTGVu\nZ3RoIDY3ID4+CnN0cmVhbQp4nO3NMQ0AIQAEwVNMTYKOV4AZKhosIOQxQUNmuq02uWynZ2WmpWac\nLreHAAAAAAAAAAAAAAAAAAAAAPCY7weB+gXnCmVuZHN0cmVhbQplbmRvYmoKMTggMCBvYmoKPDwg\nL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAyNjEgPj4Kc3RyZWFtCnicXVE9b8MgEN35FTem\nQ0Rst5UHC6lKFw9Jq7qdogw2HBZSDQjjwf++fCRu1ZPg6T7ece+gx/a11coDfXeGd+hBKi0czmZx\nHGHAUWlSlCAU9zcv3XzqLaGB3K2zx6nV0pCmAfoRkrN3K+xehBnwgQAAfXMCndIj7L6OXQ51i7Xf\nOKH2cCCMgUAZ2p16e+4nBJrI+1aEvPLrPtB+Kz5Xi1Amv8gjcSNwtj1H1+sRSXMIxqCRwRhBLf7l\nq8wa5FZexfIAzwwuf9wiQ5mhyvCY4enOuKYGdXbrW4M6hsuyiNQMl4zXOM/95Tha3OOmmy/OBclp\n2UlrVKk0bv9hjY2seH4AHtCFLgplbmRzdHJlYW0KZW5kb2JqCjEzIDAgb2JqCjw8IC9DSURUb0dJ\nRE1hcCAxNSAwIFIgL0ZvbnREZXNjcmlwdG9yIDEyIDAgUiAvQmFzZUZvbnQgL0F2ZW5pci1Cb29r\nCi9DSURTeXN0ZW1JbmZvIDw8IC9PcmRlcmluZyAoSWRlbnRpdHkpIC9TdXBwbGVtZW50IDAgL1Jl\nZ2lzdHJ5IChBZG9iZSkgPj4KL1N1YnR5cGUgL0NJREZvbnRUeXBlMiAvVyAxNyAwIFIgL1R5cGUg\nL0ZvbnQgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9FbmNvZGluZyAvSWRlbnRpdHktSCAvQmFzZUZv\nbnQgL0F2ZW5pci1Cb29rCi9EZXNjZW5kYW50Rm9udHMgWyAxMyAwIFIgXSAvU3VidHlwZSAvVHlw\nZTAgL1RvVW5pY29kZSAxOCAwIFIgL1R5cGUgL0ZvbnQKPj4KZW5kb2JqCjEyIDAgb2JqCjw8IC9E\nZXNjZW50IC0zNjYgL0ZvbnRCQm94IFsgLTE2NyAtMjg4IDEwMDAgOTQwIF0gL1N0ZW1WIDAgL0Zs\nYWdzIDMyCi9YSGVpZ2h0IDAgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Gb250RmlsZTIgMTYgMCBS\nIC9Gb250TmFtZSAvQXZlbmlyLUJvb2sKL01heFdpZHRoIDY4MiAvQ2FwSGVpZ2h0IDAgL0l0YWxp\nY0FuZ2xlIDAgL0FzY2VudCAxMDAwID4+CmVuZG9iagoxNyAwIG9iagpbIDQ4ClsgNTY5LjMzMzMz\nMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMKNTY5LjMz\nMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgXQo1NiBbIDU2OS4zMzMzMzMz\nMzMzIF0gODcyMiBbIDY4MiBdIF0KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE0IDAgUiA+PgplbmRv\nYmoKNCAwIG9iago8PCAvQTEgPDwgL0NBIDAgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMCA+PgovQTIg\nPDwgL0NBIDEgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+\nPgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCA+PgplbmRvYmoKMiAwIG9i\nago8PCAvQ291bnQgMSAvS2lkcyBbIDEwIDAgUiBdIC9UeXBlIC9QYWdlcyA+PgplbmRvYmoKMjEg\nMCBvYmoKPDwgL0NyZWF0aW9uRGF0ZSAoRDoyMDE0MDIyMDE3NTMyNS0wNycwMCcpCi9Qcm9kdWNl\nciAobWF0cGxvdGxpYiBwZGYgYmFja2VuZCkKL0NyZWF0b3IgKG1hdHBsb3RsaWIgMS4xLjEsIGh0\ndHA6Ly9tYXRwbG90bGliLnNmLm5ldCkgPj4KZW5kb2JqCnhyZWYKMCAyMgowMDAwMDAwMDAwIDY1\nNTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDA3MzYzOCAwMDAwMCBuIAowMDAwMDczNDQ0\nIDAwMDAwIG4gCjAwMDAwNzM0NzYgMDAwMDAgbiAKMDAwMDA3MzU3NSAwMDAwMCBuIAowMDAwMDcz\nNTk2IDAwMDAwIG4gCjAwMDAwNzM2MTcgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAw\nMDAwMzg4IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMTMzMyAwMDAwMCBuIAow\nMDAwMDczMDYwIDAwMDAwIG4gCjAwMDAwNzI3MTIgMDAwMDAgbiAKMDAwMDA3MjkxOSAwMDAwMCBu\nIAowMDAwMDcyMjM5IDAwMDAwIG4gCjAwMDAwMDEzNTMgMDAwMDAgbiAKMDAwMDA3MzI3NyAwMDAw\nMCBuIAowMDAwMDcyMzc4IDAwMDAwIG4gCjAwMDAwNzIyMTYgMDAwMDAgbiAKMDAwMDA3MjE5NCAw\nMDAwMCBuIAowMDAwMDczNjk4IDAwMDAwIG4gCnRyYWlsZXIKPDwgL0luZm8gMjEgMCBSIC9Sb290\nIDEgMCBSIC9TaXplIDIyID4+CnN0YXJ0eHJlZgo3Mzg0OQolJUVPRgo=\n",
199 "metadata": {},
200 "output_type": "display_data",
201 "png": "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\n",
202 "text": [
203 "<matplotlib.figure.Figure at 0x10b0ecf10>"
204 ]
205 }
206 ],
207 "prompt_number": 9
208 },
192 },
209 {
193 {
210 "cell_type": "markdown",
194 "data": {
195 "application/pdf": [
196 "JVBERi0xLjQKJazcIKu6CjEgMCBvYmoKPDwgL1R5cGUgL0NhdGFsb2cgL1BhZ2VzIDIgMCBSID4+\n",
197 "CmVuZG9iago4IDAgb2JqCjw8IC9YT2JqZWN0IDcgMCBSIC9QYXR0ZXJuIDUgMCBSCi9Qcm9jU2V0\n",
198 "IFsgL1BERiAvVGV4dCAvSW1hZ2VCIC9JbWFnZUMgL0ltYWdlSSBdIC9FeHRHU3RhdGUgNCAwIFIK\n",
199 "L1NoYWRpbmcgNiAwIFIgL0ZvbnQgMyAwIFIgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9Hcm91cCA8\n",
200 "PCAvQ1MgL0RldmljZVJHQiAvUyAvVHJhbnNwYXJlbmN5IC9UeXBlIC9Hcm91cCA+PiAvUGFyZW50\n",
201 "IDIgMCBSCi9NZWRpYUJveCBbIDAgMCAxNTIuMzk4NDM3NSA4Ny4xOTIxODc1IF0gL1Jlc291cmNl\n",
202 "cyA4IDAgUiAvVHlwZSAvUGFnZQovQ29udGVudHMgOSAwIFIgPj4KZW5kb2JqCjkgMCBvYmoKPDwg\n",
203 "L0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxMSAwIFIgPj4Kc3RyZWFtCnicxZi/btwwDMYz\n",
204 "a+wTCJ3aRSEpiZLGHtAG6FbkgL5AmwTBXYCmQ16/dJycRcWq7SV3k81Pf76fzyZpo703l1/Q3v61\n",
205 "ZL9bsE8W7ZUBOTpajOR8ycGnKOcHdZ6Tw0KY5fAgojq9Mw+yKA2Lgiv+9WdvZeCVoewCR6ZoCVyk\n",
206 "jHIkewVw0IYPdTix8y/hao0qKvveiHOhcF5t6qJgqWDPRRXlkwmzm92vHp1g8rYzzf5on8xuby+/\n",
207 "oUWw+xsjO2L0w+gk06Ld/zKfPn64wAv4bPf39uu+XeGZwITgAuSQCQMVZbtRlHWt1fYbZRNCIAdA\n",
208 "5F/mnjAWEFiiEb0vlGNSCI2iELRWIzTKJoQYXSglJU7PcyeEpf9BDFAJWDhQZgXRKApCazVEo2yC\n",
209 "SOiQ0efhCnANQQsQhRz5BNHHhEFBNIqC0FoN0SibICR5QCjxde4E4RcgELLDVAqCTPQ6nzSSwmjE\n",
210 "mqOVNoEgkCuFwuvkiSQskVBwSDTejKhJGkmTaFGRNNI2Esyu5PLyp9QkcYlkLpHr/K4J5jK8Gr/R\n",
211 "uQ9Sc8bxlW1esL1YD6BjermIrTGdHI8VAXm47sDr8unkz6Pj/Mb1FG1c18Nnw6tcyzM/bIahMryU\n",
212 "eCZzUkOk+rSWp2hjuR4+G15pGUazvjgPle+lJ3RyGIPUvje+p2jjux4+G159qSPIZpXl9fc0RykT\n",
213 "byxP0cZyPXw2vNby8yy5p6hynVe77vRaXKeDFemDNxVUuc6JXKqfQWkIJs9/ZpMColBaaSmyffxt\n",
214 "f9qHsZ12BFKZMbIUZxkbEBOHBCw20unEPk49atUtXxlhoITscwhNv5cdJ5TWC1TVO2ghBUkqYQRX\n",
215 "S1WC9Mw788O+J9S896ON0gXIxBDZqwp4aBUxFQb3puE9CefA6rk/Dk+NzJQcSZLgFZdSzH+IK+Xd\n",
216 "wXr2pW/1LnNhOaeowZRiusjnBevZP9o8ZK4i60pTrp8vpZgu8nnBevalSQfHsiYDSJekTCrFdJHP\n",
217 "C9azL2BFsn2W/MaQGrBaMV3kM4N17A+vI0k8JOZEgM2nESWZLvR50boAwoaylaTvBEneMzSbkkwf\n",
218 "+8xwPYLx7YtYXAafC2s4JRkpW5B5jtvW0gg3mk4+UZSmm9SHrBX9z/WKNxc9fsvXuu7w+ebt2ph/\n",
219 "ACMXFgplbmRzdHJlYW0KZW5kb2JqCjExIDAgb2JqCjg3MAplbmRvYmoKMTYgMCBvYmoKPDwgL0Zp\n",
220 "bHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aDEgMTkgMCBSIC9MZW5ndGggMjAgMCBSID4+CnN0cmVh\n",
221 "bQp4nNS9eYAdVZ0vfurudavq3rr7vvftvdOdTtIJi6QTsnQATdhCgsYECRAWIVFAwAUGWQL6JjDj\n",
222 "AEEQRJYAvsnNnbZZxjfkzVMExhl7HImgeZBRCIn6BnUcRudB8vt8zqm66QScef/+DqnvreXUWb6f\n",
223 "73pO2QpNCBEH8Ynq8iVLlwleawdAhLl81cozz//y80lcm0LoZyw/8+zFIiXCQvvNBj5feebw6M3v\n",
224 "9H4RL+zA9YbzP3ne5v959xPrhTj9QSEC2fOvvrIaXKRVhTj3RDyvXrj5ok9etDjUI8Q5T+Od0y+6\n",
225 "7NoLR5ee8b+EWLdJaGdt2LTxk9fkfn3RLCFCWSFWbN10wXkbn8ze+XPUHcT7Y5twIzjoXYPrjbju\n",
226 "2vTJK68pvnny6UJ4QujPvvSCT12+7NTTbxHarheEqC+57Irzz1v629+uRv8fE8Ib/uR512z23hfG\n",
227 "2LWtHM/l533ygq985Ml/EdqPMD/jbzdf8ekr77zla3cJ7fVpjGHW5k9dsPmkX106T4i1eK4NKd6I\n",
228 "xZenf/fv66Mn/psoeCWjPtds3cDf7994/87Daw/t8x7wfhOXuvAIVfCe98ChPyM9vPbwWryliaOK\n",
229 "dhPvgG4UQXE2sFDPw5iZ0B8B0YTXE9XuEH7h89zuAQfEqepX+7gY1bKs5/d6+OPFUHauEtVT3LZP\n",
230 "W/GRlWJcVP+vB2P4a45BW4rbX5X9/sh7j6jiPw+Hqv3OGU0aDf3lBxxXiw2e3WJEHm+K1Z7TcX3s\n",
231 "8aawPINigzeMOj8UG7SQPJZrocNv4/gNzj3az0SEbaE/HhHvdbK+OhaLEW9LLJS/H3B4TlJ1ZF+D\n",
232 "YlQeJ6E93McYz3rfcf7h99Aexx7wnHT4t51jUGTkEURbziF+LU7gr/cs595u5/desQrHWu3bouKt\n",
233 "igF573wxoX0KeLwmTtd8wtR8h/8Vv4tw1MSvD78p7/9OrMBc0e7hn6tfjHNQfERep8XZOBahvRzu\n",
234 "ldFeL377OB/gPIdtoM+P4HoA7y3FcQ7ORz7gGIM8baEkEj/5zulixGn/bK0XfeZkvyPOr8DRLXYc\n",
235 "Xos+ycez0Nc7fA9jnIvjQ9oJ4gQcS1FvAs8mtQ+j/q95Lk7g2OX88A6Of0b9CTk29nsv5yYC4N/J\n",
236 "ePYbZ/wT+L0Jvyc74+Vvg2OceXjvlfwpy+tBsQkY9+AY1y4WY9rpoqL9iajgWa98Dt5D9kfA6zEc\n",
237 "Ie8i0e3OF3zIuWMhTzG+YRyDwOx+HOvdA+8tmHFs1E4TpxILjCGrPSFqPDCOk4gRecyxE2+pB4Pi\n",
238 "LNSPyHGAlxjnIMZZx5z3oP8JWRfXcu7HHMRIyv8PRQS/PLfdwzN4+BD6zfBgu5RPxecO33GI1ezH\n",
239 "weA3zvEmx43fFxxZIS83eL4movI4IIblwTHMEVWMYcLzMfDkTdGn/Rp8rYgLtP9z+Pe4l/N8TywH\n",
240 "j9fTHoCHZ+BY7vyeQZkhj4+yCa49mGkXaAM+wDbQJsw8aB+UjYA+hA6/C9twBo7EMfahc3RshGsn\n",
241 "XJswsx/XJhxtG44cH2QjcEgb8UfsAnV35iF1Venr+/Xx/GMOhbsJbF7B8VvgEqLezNQd58jDy53j\n",
242 "6Id7xGfqCGUURxJH2ZXRzgF5nHl8kOzJQ8md3ZGzFnj7U8jlh6UOSUzJC5QR+kld9/uFN+CUoJ8l\n",
243 "6A8GPSy+gN8fCgZDekgWf0g+VlX1gN8pHtwP4K4v6A94vfJFr9/n8Xn8Hq8X9/y4CPg9HlUbHQb9\n",
244 "Xq9XvYr7QZ8PV6iuuvSg75BHvqZKCC+GQvINtoIzHd37fPJ99hX04AJPvQH+C3k9ul+17vehbTxj\n",
245 "XVnT4xQvJhyUcw3iKYYu5+Rx2RB02CCLywd5TSYcKQ4jnL5QAoHOfdWjnJUzGE6albzu5P0cHSbi\n",
246 "DegIBcLEQfYY4CHHEQgFvbI6miMGDg6BkDNMVtTVKCQOuoTOBzhkL152DRQwM698BcwNeDzqBXQY\n",
247 "DKi2MXX8C3KEAY8aN36CIY+O+kFXNnRUCoV8Xh8v0KDXG0b3nanhDnAIeCkHpCGfJxzwOWOTDA2Q\n",
248 "QcfgQJaS/ayAriTPPYoNQZcNnHIw6PKBwiCZcKSounogEDgKGKc40/F04J2Bgyv1Ph9nHwQOhhEI\n",
249 "CK/sISj7JeoBPaRwgFiGdV3ngRLQg+74QsFwh1HAEwhBiPRAUOHgpWhCOL2UXdTzecl6VRsdSpTV\n",
250 "WDHPkMTBq3iKH8i+DviC7kzDeFnXMQFeoEGv1whSYp2peX06NYU4hAiF7vMaDg4BpcAB1vUeXcA+\n",
251 "8i9ITcZ8A5y8R7Eh5LKBU5aK6FV4Kia4KLmMCIU7Aul35VjWcabjTBW3fEqHleLI9wkuZh9CXGxa\n",
252 "xEH2EFK9YADBsK64iREaum6YhiyhMAcYUsMxJGK84cU5Xgz5wzhcHMAYL7jmM4Kogq5wrmZomgE5\n",
253 "uQD1z4P7IRqZoItDgDgYXsUJSkaIF1AiH+URrYS9XgtjVTOhdPkMWhlw1qdDJYNhv9cM+h0F1/1S\n",
254 "vQNKrGcU6LguK3AYEC925PEqHrhsCKPoussHKCY4ASY4KDlA6SFDckExNujKs6NIUhR9zkyU4Qr4\n",
255 "HJFSmhSCxOqGEJYVDAqfahH9KoRDR3AIGuGwYTk4yEE4Q7X0o3EAa4wjOODuDBwCXr2DAzrUQ+5Q\n",
256 "PBT+4NE4YOoGbuouDhZwMAyFAwA0vD6Jg+QzrBVxkIOAPhIHw++1HBwoUR+MAyYcDrP9MI2wrljq\n",
257 "IRvCsig2HIMDLhUOZEIHB90KdpAJhf4LHOSYj8IBbtanW0JEoh0cdLcXMDysHAlGCBzMiClLyJS+\n",
258 "Qo4UOLiS4w2asFI4NSF/jgnkXZpyn0nnAubSvUqwo5EgJ+eTPXl04gCtD3kdyxEkDhbqS5/ENyK4\n",
259 "ME1lFzAXy+uNuBKr3LBJa4/24Mrwzwx4IyHHdjpKSy5I7s/EgXMFDkGSkMIBXYcdiZNsQKH7hLvX\n",
260 "Hf0gE1Rx5BbF6ozGASZ0xKBRFNVUdQZENFzBI66Go4N59+kRIaJ2KCR8snPioPAImR0cQtAFK2rJ\n",
261 "4vBe4RB1OgXOIQvQhYFDSA9IHHyQfcQqIQQjlsTBBw66OERRFXOTI8E9X1ji4OvgEA57LV94Bg54\n",
262 "2bJg43kBHPx+G91L5hIHr9/y0SiiFyPEqgFf1MEByuHIphTGIwXWLSyZrVNdMV/JUq8ffFc4yKFS\n",
263 "9MLGERxwn0zosNrRnajigjvcGThQ8OkjjsaBouPgEFI4GFEh7FgHB4P9spi6lD9wBwpKDBwcwpZ0\n",
264 "2lI39KghRyJxiEgVClpQcxcHHSjoxIFOPugzdAcH3bZDUshCHC/4AZbDV+kuDiEHB91wZxrFRSQC\n",
265 "28ILhQP4pWYi9cECpjq0Ba4MUUUk4IvpAcWQoOVEe9LPzyh+TpYSTXUNozUcEgdDab6UNHVKHEKy\n",
266 "O4cJYSdqUUCZRlRxQQ23g4/UeZ9PxtvOPakHDAoCjsu3JBbAwRYiFtN14XdxUI4Agm+pWB/MAAaR\n",
267 "WESWcASj1cNyOEbMcIfjg26YcOahiN7BQXdw8Ec6OPiVHqFDafXCfOANGz7DwcFJLzAWfxT1OzjY\n",
268 "R+MQ8ftjEgelHuzij+FAJzYTB/9MHCxKSJjqGjalKTC8fgcGS7JBzVPioAaDKzBBGisZQToVYnqn\n",
269 "KAVxcJCRke4GWkfhEDiCgwlHbcSEiMeJg2It+pE4gOEKhzD6BwbRWFSWcJRO23BxcDXYp9uYsGmF\n",
270 "olBzmaJIHGBxwKQoJQ04hB0cwujQoLLLC68BHBhBhn0qd/KHXRxMsok9xPByNAqF5gUa9PvjkEJH\n",
271 "BNBDIAocwmgvaIUDqBr0xcPBDg66jLoJ4FE4kNl4YChiyJAQFs4yLcltxQYUJZBh2R0uwQSJg/TY\n",
272 "Lg6uHaPPCTvPpGNBR2EXB4MJQsBNQBRqHJ2pB/0WcEgkwmEHBxMdSXmIGNGIEk4oKDCw47Yshm26\n",
273 "44sYCUtqEHEO27BYFnAImw43wRVKNphkc4Yhv4VzBRw6NPkgTFvsxalJHAx/0NUHmIKY33RjNMOI\n",
274 "40Xbho1Hd3jR9vsTGKtKaqQTsyFmBvKSoGUETMMO+hOGxMxwgglG3ob/qBJQzA4bVFcjYkqWEgdL\n",
275 "ab4yOCiRiMsHGEhwwrb5xCmyqpUwHHNON+7ad9PpkSMMONWdgEolUcruyLDTbyWESCaBQ0CZPuAt\n",
276 "cYi6OIQdHBIKB1PiYKqRzsQhFo6ErYgOOGbgEHZwsI7GAR1GTEaBEgfofSSMTMj0d/QBU4/5I6Zl\n",
277 "gu0cTRygxGKYA2QYViLm9yeVmVaqThzAaIUD/sWC/qQRVFZep+0Od3AIzMQhGjWNsEl1RTgIAxCJ\n",
278 "EAc5t6jDhg4O4f8Eh8gMHCz1SAq14UwHnSlHYzoBFV2+41kgShE4auKQShmGCEizg6E5AzDtqGrF\n",
279 "ChvAIJaMyWLGaDxNVTkhe2PHfiNuRDEoPWZY7vKLQRxMZFExvGACB9PBwUSHUeIguezD/Sgj+Rk4\n",
280 "QAYS/qgbK5tmAhoSj4ckDrAScb8/BSlU2i9xiAEHE5MNRc2gZcZD/hQibDlR4MAuKajH4KCYbVg2\n",
281 "cLCACBnq84PvygLL1yl6UTIiEJaw45JMMB0f4jAiklBckDhIJTYVZ/5LHEyaeeIQTQqRTndwwBhs\n",
282 "qRe2GVM4GNBd4BBPxWWx4hYHoHBIKR1iRGEmAB3cR9yMhJxFLqIjcYiToTr46verztFh1GIUKHGA\n",
283 "I4pSYy1nDRFvYerAATGaqax1CiBKHCCtSP4TgWAaY1USKZPYOLTPxSFCHNKmim0MI2r8ERwo2hZx\n",
284 "MEgsaYN8QQUCH7FQ9KK2NCyyO+BAJsg5y5Gp2ilXHqEglrLrNFemMx0IiuKUJVNDnemjuiNxiIZD\n",
285 "gWhKiEzGNF0cgLfUtJgVt2Vegv7NRCwWTzs4JCISJhYrFZWWDN0GgIPt4KCrtS4/7wYsJKtxMM/S\n",
286 "A1EroHCw0KFNHCSXfQiEbIlDoIMDdDERsN1YGTjAiCQSiHnYHXAIBjMKB0xe4YBM18LUENqFYK5D\n",
287 "gYylcDBVMGFRUI9agnNwgEeMAYcIELFxTRzk3GKKDZyyHWPernAALLgjnbcqylqnrIiru+rEch08\n",
288 "tf5YHMIzQuAYcLARuEbTQmSzwCEoG4yiHzUAKxGT44WYm9CFZCYpSyQZIS+kjYpkbOWmMEUracUw\n",
289 "KLiMqLMKG3BxCCbI0DD4GnCcEDq0I65I+KLAgTlqxFnLxVu2HUgG7IgNky1nlA5ErGQS2QZsCXBI\n",
290 "BoNZjFVNXOKQcHGwESpYST2QtXTH28Ypp8xEj8WBoo0K0TjtbCwibZAvqCxPLK7YkECJxVw+0DjG\n",
291 "yQSFg5RXFjsj7zgexXL1JGI500HArfxIZAYOinVxgotkzs4IkctZlghKcafWScWIR1wcbNNKJRLJ\n",
292 "rItD9Ej32Rk4pGCxYraRJA5qsRF3zUAEF0kwLwIcIg4OEXQYkziQy75oFB7kaBww9XQg5uYskUgG\n",
293 "xjyVQphPmx4MpoLBHOyFsgxcOdKT8NERTFaPR0LRSEoP5CIKB9gzFf4ZVKSZOAQVs61owiQYEWmD\n",
294 "fGBDTGm+ZIPEIU5GmrZ0VOBEMimdtyrKa2aPaIjCIaIcfAeHkFNdRa9GB4cIpSRmhoLxnBD5/Ewc\n",
295 "EmoAkWRcpqsWeJRJJFK5lCzRNIcQVZVzMenGcCMQSUfiGJSZitjhIzhYEgfcIw4xDEt1jg5jUXco\n",
296 "Phs4UGMj7n6GFcDUOzhwNNlANJJOI06l1QgG08FgHmKgJFIu6qQcHMJxhGyRtB7Iz8DBkknRMTgE\n",
297 "gAPEKmrZCYiDHY92cJAlodhA0Ysn5NpkzMGBTOjgoBgRzykuKEMlH1C5nB4tFwe85uDgpCLS7iAq\n",
298 "RwJBHAqFSESEZIMx4C0NVDKaSjo4RCLZVCqdS8tiZ2zy4oNwSETiMTMdibk4RIhDFHlLmkmgEYhH\n",
299 "A8oJRdFhXOLAuMAPIxTnmk30CA5x4hCPxh2nGc3hxUwGDs5WOIRCBXQ/A4c0rGA0RP8U1WPRTDhQ\n",
300 "iIaVw5OGFOEQDEZALbw6MIDj5GjEhgoDjJj0Bf4QIZBSrww/SjKpcGBnuCQTOGvlSBRoM3CIxaLu\n",
301 "M9WjwsGZiLMSQhzUjSSsWQIpP3EoFomDNDuwfimpaSk7rXCAmEegC5l8RhY7A97HbDnWeF4ld2gu\n",
302 "GM1Gk9FE3ATPwwG5CAzZD0aCNvKWDF6wjWACHFRuDR3GY/C6UbLVj8QgTo21g86aZSQYTwRzwbjK\n",
303 "WTiafBA2GDjAT8bhNTOhUBH2QumKxCGDMNAO2XY4aeuoGg4W7bCtZDIlxZMhaPCoEqJoo0IsBXFA\n",
304 "WB6JJ4hDMknLk0wpNlD0FA6RuIMDmECbrEamGJHIKy4oQ2W7o3Z6pKSEnHszcHA8fEThkMwLUSpF\n",
305 "o+/HIZNycIhGgUGukEPJ5mLZOBtUlQszcMgRh6SVicYNtZsIU9LBAfVM4hBQnaPDhA0c5IU/Hg8m\n",
306 "HByUqEYCiUQgh/oJV+IKACWbRb4A2w0As6FQCWLg4gDf5+JgJO0wqoaDJQeHaCRp/VEcKNnROM0m\n",
307 "wnLpC/yKDR0cKHqplMsHKmUGbKAtcHitaheO4KAeyVFD0WkaaJ10555aNzedVIR2BzgkI8ChIES5\n",
308 "TByk+U+kUypATcdcHGAoC+i9mJMllotTJhUOpQRNGQUgaOftlJ1MWVk70cEB6ARj4FI2hpjDDCYh\n",
309 "ycqtocNEnDjEMBd/wsEhFgy7+pBIBvPBhModOZpiMB7L5ZD2wgbgxVwoVEb3ygpzoSCcRawUC8Vi\n",
310 "RioWRlUjWI4ZsqtoNK3CcIv5eDAYOoJDMknJjsbTUYIBHJLEQVkeFMkGiUPa5cMMHJyRKUakSooL\n",
311 "0rHKRzEVaHX0QXfqy0RPrQQoVqRhzFKRcChVFKJSsW2hSxyS6XRGDSCWld2HIOZ2MZvNl/KywBax\n",
312 "QQVaKTkThzSsaSQHHJwdKdwlDrqeUzikOjigw2QcqikviAMiEAzMxSEaTBKHZCzl4lACDvm8wgFe\n",
313 "M6/rFXSvrLDcNssRB13hkIjljWDFwcFGYIHyfhxCIZoYWpYM3FcinZC+wK87OGQUG7Io6bTDBwYM\n",
314 "4ASY0MFBMcLFgYXsPxqH6H+KA8KrVDSsp0pCVKvEQQoBRCQrLV42nss4OMCe53KFckGWeCEh1UVW\n",
315 "LieVc49BFAuxTCyVjuRjSXe7CiyKhuIhXc/HUc8KpSDJKrxAh+kEcWCM6E8m4MmBQzzk7ChEQ5h6\n",
316 "IZRWOTxHUw4l4oUCsm84UOBQ0PUqZAbsZddcwc8jIInrcfinuAF7aYaqcVPFEtGMCsNhMEJHl1Qq\n",
317 "m0WFRJb+LpOwYQrSfl1iAC4oNtAEZDIuH2wbl2ACfaNTlO6UFRekoVE8kfYi7kwHguLMxFmRkmuX\n",
318 "St5hzNLAIV0WolaLxYQu3TBERCUK2Xg+q/ZsUnYMulCsFGVJFJNsUFZOVlJyRBKHInBIp6MSB7UZ\n",
319 "FYPBnolDuoMDOswkEYXKiwD8YAYe9ggOdghTL4YyKofnaMqhZLxYNA2LF7oOHGoQA2Wh5XJqB4cM\n",
320 "cSiaoZqDA5McmuYPwCGdBg4wflm4r2QmIX1yQLGBOEg20ARksw4fUHAJJiQVswmUql1J/Cc42C4O\n",
321 "uPU+HJiCZeywnqkIUa8fwSGbzckB5BL5nIMD7Dl6ryocksUkgzpVuYqYLillIxQvxbOwptFCPGXN\n",
322 "xCGBi0ICeEVCGUiyCi/QocIhgbkEUhIHw0iEjBk4lFA/oyLIZLISSiYcHFJ4sajrdXSvvKHEoQAc\n",
323 "EnoiYWUSRioBHOoJU3YVs3PSWjA1DoU6n2HxjKYeFVI5qGUqm5Q+WeJAY5TLdXDI5Vw+IHBzcXBH\n",
324 "pnCoKi6oSFf2K+124ggOTv0ZOChW5CQOhp6pCtFoxOMinJW2MJfLS4uXTxQUDrF0LF4pFEq1kizJ\n",
325 "EpPrpKycqqWP4FCO54CDXTyCAyKbGHAIh4vH4oAOsymYSHkRQDyShWU/gkMslM2GyqGswoGjqYbg\n",
326 "jEoWMnsUXS+Fww3goCy03J0sIkBPoD0rmzBR1Qo1EpaKrWM5aa6ZGh+Fgw6O5/OJZDyVjxGMZDwL\n",
327 "AAJhiQG4oNhAU6xwAB9QcAkmpBSzpd2Qpaa4IAPN9+FAy2k495yldCclJA6IJLIxI5ytCdHVRRxk\n",
328 "OAQRKagBJIt5uZ4OcxOHLpTrZVlS5RSDOlk5Xc/INAfN6YlKIpfIZu1SIq1wQGoCx6kn9XC4lARe\n",
329 "ET0LSVZhHjokDkaCsXogndIlDknd2dOK6TAFFdTPqggylarpqWS5bJkROlFdL4fDXZAZ5Q0lDiWk\n",
330 "RclwMmnlkib8lqV3JS0V08XyMrxkaqwfXehyUSFdgNlM51PSJwcUG+gFJBtoAvJ5hw8ouCQTOGs1\n",
331 "MlW7rrigMg7Zr0o8nOlAYZ36M3BQrMgDhxxwyNWFaDYTCReHfL4gPU8hVSqoPUwIJXSh0qjIkqqk\n",
332 "O91nGhkVNxGHaiKfyGXtciITUV/9wLXqcT0FHMop1IvqOUiyCi/QYS4NHGBkUqlAJq0jEjTNlG4q\n",
333 "BsV1iGAV9eVaCkdT19OpSgU4wInixUo43ET3ykLLTbAyAvRUmPFaysykKpbeTFlqbEhyGNbQYBwN\n",
334 "AyZcLDJSVzikpU+WONAYFRQbaAIKBZcPCShlCUzAg5RTFA4NxQUV6cr7KvFwpgMcnJk4WxrEQb3P\n",
335 "FCwXN8O5hhDd3cDBkGFptlAoSotXTJUdHBA4QBeqXVVZ0tUMG5SVM11ZOSL6zmQ1WUgivSgnj8XB\n",
336 "MN6HAzrMZbgvp3DI/Kc4cDQNHc6oGrEYv2fC4aphdEscKFFy80XigMlG8ikLVSN6dyry/4hDhmYz\n",
337 "U8goHAyJAbig2EAT4OAgAyhcggkZxWwCpaL5LsWF/wIH3HJWyuVafgeHfNw08l1C9PQkk8KQYSn0\n",
338 "sSQHUEqXixKHBBxWo1yuNWuypGsZqS4s2aZadJI41IBDPherJLMuDkloiZ4GDpU08LL1PCyKCvPQ\n",
339 "YT7DfTmGisFsRs8nEqaZdnFI6Pm8XkP9fNqJIrv0TLpWkzhkFQ49kBlloSUOFQToaSOdjhTSVjZd\n",
340 "i+g96YgaW6JI/qVpMI7BIZ8vlVAhWwIO2WJW+uSgYgO9QAeHYtHlAwI3cKJWw4O0U1TtpuKCDPiz\n",
341 "8r5KPJzpwHA6M3G2loiDer8IY1ZImEahKURv7xEcYP+k5ymnKyW1p4/+uyqVWrfCIVPLskGFQ3dO\n",
342 "jgiwhlP1VDFVKMarqWxUfeQGHMKJcDpsGFWJQ7gAi6I6R4f57BEcsmHggIGFI2qLNwEWhevhfLrg\n",
343 "zqgZzioceBEO1wyjF90rbyhxqIYVDlEHh3BvB4dSB4fwzKKHC4VyOZ1JZstwXxKHgoNDUXoByQaa\n",
344 "4lLJ5QMCN3CiVssqZhMohUO34sL7cHCmA8Pp3HsfDiXgUExEjEK3EH19qZQwZFgKEXFwyFTLak8/\n",
345 "n0zBJtV76rJk61kGdrJyrgexdVYqYjjVSJWIQy2Vi6qvEUMpOM5wBjjUMsALOECSVZiHDgvEAcY+\n",
346 "kwnmsuECPKyVCUcVi5LhQj7cQP1Cxokiu8PZTL0ejdgMZgyjbhh9kBnlKeVmZA04ZAzEzcVMJJep\n",
347 "R8N9maiKrZFsMrzkUtEH4IAKOeKQK+VkbBQkG+gUHBxoistlhw8ouCQTOGs1MhXN9yguyIA/J/tV\n",
348 "CaAzHeDg1Hd2LOSeilK4JHGIGsUeIfr70ylhyrA0Xy5XpOepZGouDvCrtVqjtyFLtpFjg6pyr8IB\n",
349 "sIbTXelyulhK1NN5W1cfrDg4mGadi7WxcLGDQ39/qpCDq5IXwXzu/TgUw13AoejOqCeMoKABHOBE\n",
350 "gUPDNPshMyoqkTjUkShl0J5dykTymUY03H8MDjTcR+EQBscrlUw2laukCEYuXSgCB1NiAC4oNtAE\n",
351 "uDjIwA2caDRyitnEQUXzvYoLKuOQ/Ur/eQQHy5mJs9U6E4d4vJSMmqVeIQYG0mlhyrAUIlKVnqea\n",
352 "rVUkDqlCKg2b1NXXJUuuK0+ZlJXzfVyElYoYTjeBQ+koHNLQknCWOGTxTixcgkVR4TY6LOa5T82Q\n",
353 "PQgjBH8ZiWRdHFJhmORmuJgtZdV6Tr43nM92ddkR5lF5w+gyzQGIgfKUHRyyJuLmcjaCqnZ4IGur\n",
354 "hChVIf+yXCqS3O/AYJRKtDDpfBU45Cs5GRsFFRvojSUbiEOl4vBB4QAmyCRb5Rmqdp/igky85KOs\n",
355 "SsSd6QAH594MHBQrKql4vAwcyn1CDA5mXBwgIjU1gGy9KvdbU0X41Xq92d+UJdc8gkOhvyhxAKxG\n",
356 "ppmpZJDmNTIF2/m0J40AxsgaptnIFrLZuFGCKVKdDw4qHORFsJA3FA7q0wpM2SiWjKYxA4c+I59t\n",
357 "Nu0ocEBto2mag4gnVVTCN6INJEoODlHED7Yx2MGhKnGg4TaOLhIHqEEN7qtQyWfKUASJQ0V6AckG\n",
358 "muJq1eUDAmhwotl8Hw79igsq85P9Sv+ZdaZjGC4Ozlars2RIwwenUk4Bh34hhoYyGWHJ9KBYrdak\n",
359 "56nlGgqHdDGdgU3q7u+WJd9dYICtKvcXZdovcejOVBFdJLsyxZjzMVsGjtPIGZbVxUXzuFGGRVHh\n",
360 "NjqsFPi9QA5zCRULiKjSkUjOcBBMGxDBbqMCY6HW1Qp9RiHX3Q0c4EQLptm0rCHIjPKUcnO+Czjk\n",
361 "LMTNlVy0mOu2jaGcrXKcdJX8y3HJ7hgcyuV6HRUUDtW8jI1CZAOdQk2xgaZY4ZCWOOASTJBJtsoz\n",
362 "VFbVr7ggAyC1QSD9Z86ZDhTWmckMHBQrqulEopKyrQpwmDUrCxxkelCCH5IDqOe7agqHUjoDm9Q9\n",
363 "0MFBmi2W4oBaDAesRrYnW81Wyslm9mgc8sChmQdecaMCSVbh9qxZEocIjH0+38EhPwOHqtGD+pW8\n",
364 "E833G4V8d3fMjjOYMc1uy5oFMVBRicShiYQ1b+XzsWo+Wsx3x4xZ+ZjKcdI1GebTcB+DQ6VSr6NC\n",
365 "sY4wolgryNgopNhAbyzZQFNcqzl8QMGlwiHvFFV7QHFB4SDvq0T8CA7OTJwtb+Kg3ufSUDVtW9UB\n",
366 "IYaHs1kHB0THDRkBNPLNusQhg8ABNqlnsEeWQk+RDSrQBstyRBKH3mwNM0l1Z0suDlloicShm5sX\n",
367 "iRk4oMNqsYNDqWggM8LAXBwyRrVq9BpVhQNHM2AU8z09wAHBDHDosaxhxJPKU8rP7rqP4GCX8j0x\n",
368 "Y9jBAXGWdJvvx8GsVBoNVCg2EEYQhyoUQeJQk95YsoGmuF53+YAAGpzo6SkqZhMohcOg4oJMvJRs\n",
369 "yjgm70zHwQGvyQVZtfetWFHPODgMCjEykgMOMj2AqnbJAXQVmg35HQj7H2g2e4d6ZSn2FimTsnJp\n",
370 "CDlOUeqomevL1XNV4JArxdWX68DBzJgFEzgUSgXkKlVYFBVuj4woHGDsCwXgYEocCurTFEzZrNbM\n",
371 "PtSvFpxoftAsFnp7FQ4l0+y1rBGIgYqlFA5mMlmwCoV4rWCXCr0xc6QQUzlOpiHDfDwuyFG5n2oa\n",
372 "ZrXa1YUKpS6EEaV6KUeGhsgGOoWurg4OjYbLB4kDmcBZq5GprGpIcUHh4OSBPHGmY5oRp/4MHBQr\n",
373 "GsChlrGt2pAQs2fnciIi0wOISJeMxLoK3QqHLAK4we7uvll9shT7SmxQVi7PqhzBoT/XyNWq6Z5c\n",
374 "Oe58ZJuD4wQOkUgPN5GSZq2DAzqslSKRqMKhXDIRtxAH58PRrAlT0I/6NXdGQ2ap0NcXjyUQVJYs\n",
375 "qy8SmQ2ZUZ5SfqzSY8JDYrLxesEuF/ri5uxCXCWm2YZ0m3Sg5tGFoU+hmCt3IYwoN8oyRg2RDXQK\n",
376 "XYoNNMUKh6wMZHEJJpQUs4mDyqpmKS7IxEttmKkFEWc6MJzOTJxPQGbgkE2l6plYpD5LiNHRvItD\n",
377 "tdFoygigWezpUjhU4Vd7evqH+2Up9Zcpkwq04Sqaljpq5gfyjTxw6M1XEjNxKAKHXm4iAQdYFJX2\n",
378 "jI7m6mXgAKdbLIYqZUS2WdsuHsEBpmDArBdrKrMtl2eZ5WJ/P3BAMFO2rP5IZBTxpIql5McqvcCh\n",
379 "GCkWE/ViDPFD3BwtxlWume2S6RaXTo+GwWLogwrlZq4AMMr5o3BoKjbQFHd1uXxAIgNO9PfLxQ6V\n",
380 "7ykchhUXVAYu+5VxTPEIDs5M5MK4+gZBsaKLOGSBw7AQc+bk8yIi0zSoarccQHextylxyCGQhk0a\n",
381 "GBmQpTQgcZCVKyNH4dCVrzcyfUdwyENLJA59Cod6Bwd0eAQHnTjkcjNwyLk41F0choHDwEA8lmRQ\n",
382 "KXGYAzFQEYvEoc+EhyQODeIwEDfnODjkc00ZvtCBvg+H7u5iKV/pRjhX6arIGFWPSF2gN5ZsoClu\n",
383 "Nl0+IJEBJwYGZuCgstsRxQWZAL8Ph9zRONCZH8GBS3QN4NAYEWLu3AJwkGlaDX5IRmI9pd5u+cFZ\n",
384 "DoH0LPQ+W+FQHqgw4ZSVq7ORa5aljpqFwUITUV6mv1BNyC0nB4cScOgvAa+U2YBlV+nn3Ln5RgU4\n",
385 "wOmWSnq1YjaIQ+kIDo26OYj6jZJaZ66MmJXSwEAinkRQiRcHIpG5kBkV08rPMfqBQymCPLKrFKuW\n",
386 "BhLm3FJC5fy5bnKnxCXsY3BgCIoKlR6Ec5VmpVBvEAfMqym9sWQDcejudvng4iAXnVTerbLb2YoL\n",
387 "MhCtyn5lHFPq4GA7M5mBg2JFN3DoysUiXbOFmDevUBDRY3HoUzjka/nCcF/f4OigLOXBGTiMKhwA\n",
388 "q1UcKjaLja5sf7GaVP9rJoSaVt4qWdGowsFqwLKrztFhoxKN2i4OFuIWDMyKq09E82CRNWTNwGG2\n",
389 "VSkNDiocqpHIYDQ6DzioWEp+NNRvwUNGkUd2leKI4xLWPAcHxLsyfKEDtY4uXV29vaVyodqDcK7a\n",
390 "XZG5gh49Gge6RIVDXuKASzDhfTiMKi6oQHYGDs504MCcmTif4shvUBQO+UymKxePdo0KMTZWBA4y\n",
391 "XYaq9spIrLfc36NwQCA90t8/NGdIlspQlbZBVq7NqaNpqaNWcVaxu9jVlR0o1o7CoQwcBsrAK211\n",
392 "wbKr9HNsrNBVBQ4lprB6rWp1EYfyERy6GtYs1O9SKwzV6qhVLQ8NJeMpBJXAYSgaHYPMzMBhADiU\n",
393 "o8gjm+V4rTyUtMbKSZXz53vInTKXsD8AB1So9SKcq3VXIUXEAfOic+5VbKBL7Olx+YBEBpwYGpKL\n",
394 "fyrvVqsMcxQX1EqI7FctTB3BwZnJDBwUK3qAQzMfjzbnCDF/frEoojJNa/T09MlIrK8y0Ku+RW0U\n",
395 "irBJs+bOkqU6q0aZlJXrc5FrVqVsWKXhUk+p2cwOluouDkUEklYFOAxWgFfaasKyq/QTHXbVgAOc\n",
396 "bqWi12sW4sdYrOLiUACLrGGrC8ZCrTPX5li1yqxZyUQKQWUtEpkVjc6HzKhYSuIwCBwq0Uol2V2J\n",
397 "1yuzktb8SlLl/IVe8q+Cx5VjcGg2+/pQodaHcK7WU5Uxqk420Dn3KTbQFPf2OnxAwSWYIBedVN6t\n",
398 "stu5igsyAa7LfmUcU3GmAwfmzGQGDooVvYVMphs4dM8VYsGCUlHYLg79cgD9lUEXB8Q3g4PD84Zl\n",
399 "qQ7PwGHeDBxGJA65oVI9JT/+tywHB9seOhaHBQuKzZptxzo4NBFxxmfg0OyyRlC/g8Nc4DA8nEyk\n",
400 "GdxHo8O2vaCDg/yIbshCpGIzj6wkEMclrQXH4MBA5mgYIgxBK9Vivb9YLtZ7a6VuKIJuOzj0KzbQ\n",
401 "FLs4yEQGnBgefh8O8/5fcZAbFOrbKBeHbLanELe758m/w+R1jqL6q4C+j+BKk9c+HyyXWCPGhV9k\n",
402 "xRe0AW2+tkL7gvZnnoLne54XPf/b+xXv495ve3dXk9V8tVytV7urI9Xjq0uq36wlIL3dtVl1Tz1Q\n",
403 "j9bj9VQdcVJ9oD5R31C/oPnSvj0/t35/+P96Dh/mX0oUD2qztOO009By1vM8Wn6l03KiiryPk0bL\n",
404 "x31AyzG0nOu0vFG2LNCyJlt2yiH5dxQPNYV47xPvrXzvQ+8dL8S+h3lv34p9N+47Zd+Cfce9fuD1\n",
405 "1uv/+Po/vPbua2+/9q9CvPY7HK+/9qPX/ua1R177xk+Pq94sRMgv/9riGi3p6fec6PmYEJ6/8XwH\n",
406 "9DtuT57neXheEn+keKbUcdS9J3D8rUThSvG0+Kq4UOwUS8Vz4r+LvxQrxF+JdeJW0RIvijfEN8Q/\n",
407 "iX8QnxXXiBfE98TlYrv4mHhe3CE+JW4QU+IU7Uahi7AwhSUSIilSIi0KwLEkKuBxXfSLATEohsSw\n",
408 "mC3GxHyxQBwnThSniw+LM8Ry8RNxvThJnCZWiw3iYnG1+Ly4WWwV/038qdgm/lzcI+4TT4pvid3i\n",
409 "f4nvi5fFT8Ve8b/Fa+JnYqX4iFglJrQ/EVeJc8XfifXin8VZ4rtio/i4eEz8ibhTu0H8T/EVcb6Y\n",
410 "FD8S02KRuEt8U+wSa8WjYoe4UTwiHhY/EE+JgHhJ+EQIshbUvigMERMRERW2yIsMpC8n4qImekSX\n",
411 "aIo+0S3uFr1inhgVc8RccbwYEV8QS8RCSOqpYrFYJk6G1H5SXCIuFZeJL4vbxO3iS+LT4l7xkLhf\n",
412 "fE08IR4QF4jHxatij/ixeEW8Lv5e7NMMbYlmaks1S1umRbTlWlSb0GLaKZoNmY9rp2oJyGdK+4iW\n",
413 "1lZqGW2VltVO15Lah7WcdoaW187UCtpZWlE7Wytpq7Wydo5W0dZoVW2tVtfO1WpiE/Tmeq2hfUzr\n",
414 "0tZpTe3jWo+2QevW1mu92nmiLP5M69M+AQ3bqPVr52sXaIPahdqQdhH0YpNoQD+GtYu12dol2oh2\n",
415 "qTaqXabN0T6pzdUuF7PEd6CVW7QxbTM06NPa8dqV2gnaVdqJ2tXah7TPaCdp12gLtWu1ce06bZH2\n",
416 "WXGCtlj7nHay9nnxIfFzbZ52hbZA+5T4qDhHnCkuEn8rvi7+UdwitojN4lnx1+IZcZ74hDhb08Rf\n",
417 "aGEYhf3iLXFAHBS/FL8S/0e8LX4tfiN+K34h/lX8TnxGXCsC2ktSn/f9/1uWMQdIIWQwApnrhoQt\n",
418 "hHSNQ7JOhWytgVx9UkrWbZAtSta9kKqHIFcPQLL2QKooU+dB3qkN3xVnQ9q/AA34uPghZH+j5od0\n",
419 "94r3xKQW1ELQlbvEIU3TPOI/xGHoyw7x75Dex6EPV0FzhLhOC4h/gxbdKK6AhgWgH32Uhw5C3xb/\n",
420 "Q1ygecHxE8TnxJvii+ImicQnoGF/A/za0KkoNMuGPik9ylOHNB90idozT2wC+v8I/VT4rwX6Xxfn\n",
421 "tMTgqS191Zpdmvana5/WDt/cWlLapXvXf3yopQ1Wq0svXtLSNgy1PIMtrb821PIOVpe1vM1lZ6xp\n",
422 "rK3eXr19xcbbq8uqm87b2PI15S8eXHD72uFqS5y55mLQs9bUWuNrC53TC9auPX6o5WMzPtnM7WvR\n",
423 "wCVOA5fIBvD+e0Mt/+Cp1Za3e9Wa09e0blhSaI0vWVuo1apLW7tXrWntXlKorV071Ap0xojfz1+c\n",
424 "VaMNDrYC/UOtkGrhTLyP19fefru6atRau2+/vXA7ZuBcP62JY2+Mz7yBGS99WrthlXxyQ6NW4I1G\n",
425 "rVHDiNYuGWrpg6eeuWYphlRbOwSRakFk25rHM6C1vV7QKe/yRfOa2dDAlO/Dzon/LHUipjTnbMrz\n",
426 "sWVj8lY74A8OtISaT3tDSPt0+/owyAMkz5G8TnKYpBLWrmwvJFlPso1kJ8kPSN4miYa1q9rDJCtJ\n",
427 "riDZaeLdt0kqJqoMk6wn2UbyAMlzJD8gOUwSNdkKyUKSlSRXkLztVPk0q2BovLQjOBsnWUWyk+Rt\n",
428 "kuEIhxvBa4d5eQUu6RhT0LgToZET+BUifrgoTO1HIg5vG/f8DpZBQLvVf1+Gb3kFVnuWp9/7qP+l\n",
429 "wNbADwO/DWaDZwWvCV0e+qb+2/Bp4S+EHwq/ZAij23jUfNictiYin4rmo2P2JbGJ2ObY12J/EzuQ\n",
430 "/I9UOvX99O8ze3KX5LbmXshfXjilcGHh9sJkYbq4oXRLRVS+VvmbyhvVrdUdtQOIQOr1c+vXdd3e\n",
431 "9WhPqOfcnlbvpr5Ng/cOTg1tHTowy5z1w+EHh58f/tXIZSMPjbw02jV65ZzpudV5l8z79lh17KwF\n",
432 "Xz7u9uM3H986IXLCwyf8/sSNJ3lOGj3pEwu/sPDBhd9euH9cLJpYNL3oXxaHFy9Y8u2l6aVXLn13\n",
433 "2e7lkxNLVixbsXvFj05dctrVp019OPThlz5yw0cOrFy18oerxlatXrV71U9W/fr09OmDp0+ecd8Z\n",
434 "3z+zfOaSM58/69dnB86unv3s6jWrD63pXjO+dvTckXMnzr3w3C987NmPHVqXXHf1+lkbzt2w47w1\n",
435 "5x3aGN7YfUHgglUXvHHhZZs8myY23XjJpksevuS3lz592QuXhy5fdvm9l//HFR+/4r4r3tic3Lxg\n",
436 "c+tTOz5911Weq+KfyX7mK9f4ru2/9t5rv3Pdjs+e9Lmxz09d/+ANX/uTxTce/8W5N+Vv+sub/vam\n",
437 "vTcdutm+uf/m3bc8sXXktk/dduNtk7d/4kuXfelzX/7Uf3vov/3sT/N/etmffvtPX9n2uW3T2/Zv\n",
438 "e/eO+p32nVfe+fCdu+985c5Df9b1Zz/88xu+kv/K1r84/i+uu2vwbnH3GXdfdvef3f303b+455R7\n",
439 "7tpe3X7a9s9tv2P7S9v3bP/ZvcvuPePej997yb1X33vjV6/56k1fveOr9311x32R+/L3dd83et9J\n",
440 "951y30P3/eV9z973/P3x+8v3998/dv/i+z9y/7n3X3j/p+7/wv2333/X/Q/d/5f3P3v/8/f/8P7X\n",
441 "vrb7a9//2itfe+Nrv35g9IGTHjjlgdUPfOKByx+MPJh/sPvB0QdPevCUB1d/fcnXV339Y1/f9PUr\n",
442 "v37DQ2se2vjQ5oc+99DWb4x848RvTHzjrG9s+MZl3/jdw+Jh8+GtD08/vPfhAw//7hHxiPlI9pGu\n",
443 "R0YeOfGRiUfOemTDI5c9cs0jNz1yxyP3PbLj0Tseve/RHY9OPrr7sfHHTntszWMbH9v82Od29O6Y\n",
444 "u2N8x2k71uzYuGPzjjt23PH4xidGGLbLSFJ4/gGetwHbPiBGW4PDraHh1qDd6p5udQ/vSvvebQ3Z\n",
445 "rebeXUXfu+KvvFqXb+CvmloO1KdpvoGR2fPnzUn19MydPzY2/yTvvLndjXog2DM2Nmc0nUryLwIG\n",
446 "UplYLabheG3BPI8VTMfsZNg3VKkMBUaDp4yNLct1NwOB5w5t1P7hkLjq5JOvii3IWaVYNJOI6V2z\n",
447 "B+eEJhYtP7E6r1FLJOc+7bn4vbs99703iiELoaJ1z196P+3phucXWhBe6XXEDh9qX2Fo6yYXGisN\n",
448 "zxbajS2TO6PPRT3rpnZHp6P7ot51grZmHe3UOhqhdbQruETNkdlH2r240+5G2e6YbLe90NC2jFsP\n",
449 "GDuN54wfGK8bbxuBde0rSnxSkk9KO0vPlX5Qer30dimwbmT2B4zzetneQPsKC29xgKJ9mKdvcxgL\n",
450 "3bF0RoVGZs73nk47fyvbWdleFUPtK2KofQPIlIjZsWrMu2Vqd2w6ti/mxZ2aXavWvKhUY481Dc9q\n",
451 "07V9NS9ewS3RXp9kX8Vj+/pop69/lH012wvz6Atk3dQD+Z355/Jo4Yq8bKGCFg73qha8sLDCczzs\n",
452 "bhgxxID22XZzwDvQHhnAyzZIa8DeJXzvtu9o4qWRJu+CtJr2roD33ZawW8Y0Llrl6VZ5uL2qrK3b\n",
453 "FfO+264ZzVj8uPbmQfTXEkvXtHLDhV0586S18qIfF/2Bk9YiAHm3beT6UbVlDO8Ke95t5exdaY3v\n",
454 "h/n+wRoHqU3u8D7t9axrT3jR/R+8GIgewtm9CQjPNcmtSTw6QK5cTHIvyYEUL0nGiqh5C2Y8eWH1\n",
455 "6ipqrq7ixltVPHqzAbKH5EddvASZWt11YdfVXQBidc+FPVf3gGcv95JnZ7Hrb7HrpTx7lGfvkAR4\n",
456 "GeZw9kdxuYm93wMyeW3yNg7sIG9sSrlj2s+ON5G83HD6bP+Y5BV0M3/O6EkeqmZjnjqb5Wk0euaM\n",
457 "lj1U0VQamhrBnR239ywZLZ17zp/fmZ/Tl9crJ865feKfBs8Y71504qlnx8YuPPuVxXZttLFsyYlW\n",
458 "ebhu9PaWFsf7l4wef2bEE1j3kdjiRSMy0x05/C+exzx7RI/nlnY87B1oxe2WmG6J4fa4wHSmhbau\n",
459 "FbZ3lQDnql6qXh8Frw9KurBvZR+mdn2fi24UgEZddP248APddiLqJ7KJ4VbU3pXV3m357V11gNvj\n",
460 "j/J+z3B7ugdNbuiRILff1HBxWxBkbYhnJG9S59eS3Ebysk2wqD5XkXyX5FaSt0im43wAMnlbYnsC\n",
461 "A3wGAtJ+ieQXJE9SXp5JvkhYniQsv+xgs5ZkO8mLJM+S/ILkSfkgDfIMyRMkvyJJ58CjN/KUMJK7\n",
462 "SPaQvAMyGcin8zBpy+XzAm48WpgqoNv9Bb5awKvLebacZ29SOMcqyyp4flfVlZE0xXQ5zw5SPFZ0\n",
463 "4XIHdXAtyXaSHLVxBcmzvHy8G+082/1SN9r5aTdvkLu/6qH4HiRvD5CFK2i+9pCPL4Nnk1fHbolx\n",
464 "XOTfleTfGyQvk3yPPJN69aLLp8lnUi+mUH1H+iiuHCS5hnM9QHIKiZzpAVoaOQmpcPs5kwuaZEdz\n",
465 "qol2pjjMPSQHMMxmxNuoz4LYn+SBV8oEZ+EyAtEve6gN8z2PxectWTm48tbzFyw4/9aVi28aXmh0\n",
466 "z15QXHLZqb29p162pDh/3nByc2GkkVxw/tbTT996/oK5Jw7H6nl79KwrPvShK84aDWf7KlLue6Tc\n",
467 "r/B+rj3YBVsX7BqkPAYhj5C+VmRvexvt+esgraDdSu5t/5oMKEeCqDZufLX8ZPmvy39X/mnZD7GE\n",
468 "xWv3gbS67F3zYRHhkRdPtxYPT44vXrUYIjC9GM/KdmvF3vaqU6hFp9LjnbryVCrQqa4C9UFn+lwF\n",
469 "WoGLFVCglrm3PQLMWrG9rRU0se2hvhUcKRx/n71rFBq1wt51IjRq0Yo+3l803N6wiIqwSGnU3Vnq\n",
470 "Rw4dXly6toQOl9Op7KhTikjWkPPLwfnJH/e/1Y/nPxogSiS3knyP5J8GiTDI1L1DTww9OwST+HdD\n",
471 "FCySF2bh5SdmPTsLL/9yFqVkmD2QvECylmQ7yTMk15H8gmT/XLw4f+7yuXD2n5l769y756Ldb82j\n",
472 "JsxbNg+tPTqPtUhuJfkxydhxHC/JrSS3HM8qJMtJ7ia5ZyGaWLvw4oU0vQupwCTf5t0Xx18dp2qQ\n",
473 "Q78iufpkvk9yN8ktSyinJHuWcvJLqTiPgIWT382+nPWsm7wlexd+2reAoe0pcvXu3GM5j6P73yO5\n",
474 "Dm65fTEjjM+SHMPuZ0jOIc9vo2aeQsbv6d9Pxr9BTr9MckuH8W+S8XtIXiCrd5DVz856iaz+RYfV\n",
475 "B0iu7XD5RZJzhwnK8LPDqLlgLplCcoBkBdl+7dzbwPb2VrL0aZIVJK+SvLWAsBy3/DiPw+M3XfZO\n",
476 "3nr83cfj7pvk510kU2TqOQsvIqsf442Xxzl0krfI3mvI1AMk20m2krMHlxCIpa8u9azzZ5zgEy6t\n",
477 "3jM/PWd0TDo8hqXzu3v+uB3I0Ez0aJd6QjGjPJyq9SXnDtn13nSvL5yMRtLh+Nyh/pP/MxtxgrQj\n",
478 "hnGi5vX1dGXqqXC2K57M+SKWHvDHlgdixT9uP/ppXzQZjq8G+RbiJlPktMF2IgdLspOicT0I4xhG\n",
479 "TbthQ1sJGSu119MiPkAiaPZ3F1zlj0DfI67yZ3GRdWKjVsTeZWjvUpWfZqxxHMnjJK/KIIihx708\n",
480 "e9pHFEEmt/se9wGPp+k8V4R4I/R4CDde5Q0ZNT2l42yCZAfJcSTbSV4l0XVWoXtYTZcg/cKt9Aa3\n",
481 "0gSuliEMyRRN/kSaKiKjomUkMipaJsfCtp4g+WuSFWzwGZJl6U6YMyO4YVTztS+f/pmV3d0rP3P6\n",
482 "lyd+ufjmSxcvvvTmxb9cPPv0i+bPv+j02YsH1968Zu1Nawdl7MKYtQHeG+LClne4bYMT5HfLa7e0\n",
483 "va3AdCswzNg0NN3S7FZ4b3snvN7k9dY2y+PwXAYpLs89uPC4PEeQEoBJ1f0emlQdYSkRmF9L1WI4\n",
484 "+N8O7bOHPqQ9dehO7ZxDjy9e7PnO4t8sRhwux8TcQVgyDl8kdiEOb3DhZZ2YfNs8bHqcJAbpzBZ5\n",
485 "WyY2bhx/7Psfle/Pbm8D36aG7YX2StuLBMl+zvYwiKcf57TaCxl3ro+iybejsrVOWxd32too21o3\n",
486 "rg+bC82V5nrTt2Vc32Y+YO40nzN966ZeNzk+mOAoh7YBo5p6Pft29nCWt7JIlvTh7MLsyuz6rG/L\n",
487 "5APZnbSDG+hdttH/PVc+ut8jc7he9jugHOqGKMVFZk0yf5JjXs/RHybZGXV4Ad2yHN2yRU27vV2o\n",
488 "UbdoTK8HadUc3YICtQqdPMSaJo3sxeNWXNLkdHs9g+wHSEQDyZtEOw200y70VVxUXejTUt3aVrpK\n",
489 "6K3hXTYykth0y2Jb1MIc5GzyOO8Kr8dRvJ+SfJNkAcX+HpJnSHI+1FwQmoDuTd4T2kEVfIYqmDta\n",
490 "BaXi/ZTkmyRPZ6hkWSYTtCTdjDHP4dmt9C6r6VP2k3Qjf23fyrPVZbZHEHY3yN3JjjLOl8kKx3IX\n",
491 "yQL2vp3kFJInSBawz1NIniV5hr2fxd5XEFrZ8RSbXk7yUfQ0Q3OpCMxTYh+owZrn0KGJFSs+QI9/\n",
492 "MzamzXmfLhvAWhdntzTosuboMjTXu5eYQp2h18G97ZWGazK9gM3rYihwIRgvee1dPuAX9AoVz+0K\n",
493 "UXXnNDqKO6E9eeh+7ZRDU1JnnRzovyMWbHpK7WQJOVDJ3hWCrR5OgguHafJaIK2kvSuGESXtVhPZ\n",
494 "7nB7hE681eOOpo4B1I814G1Rz3IYYrhVt3d5IV5Ze5eF4SXU/cRwex+8w664MvAvIt2a/Kp4UjBE\n",
495 "wXn72yQXMW5fQ3INyNRt2nbtcQ06+SJv/YHkpyTfJnncA/J3JHf5Qd4hCfghhvP9y/0Qw7HAsgAa\n",
496 "fyfA+wHMbxnJVJgeP7w8TC8e5stcOtlD8g5JwEALy4zVhgcNGcsNtkDLtZqG4i2KZR/XGQ7Qr/XR\n",
497 "r/VVQNaSrGHM38c8Zi2JTLffYArwsky3mQfc1XyUecDzzF+ealKA7+a0d5C8Kty57yB5gQy4WLtW\n",
498 "u40MeIa3fiIfcsYvgkwe51+BebaXcRbzScY6U1lOspajPSjTFI52dSfXeqOThf+MA/kuyaMke9xx\n",
499 "ad3dR2KQsfnzKPiBwMxsxXNp18bFbpgx/4Lex39z4rZFbq5y9mdHPIu7B91AopD5P4sPPdJounnK\n",
500 "8IirB5+SPu3mlgE9AOPbq0hGQHaFIX+e6ZYhFWE98xTvNLKTXQHfu5PCsi1YpG10ctPWPji59iqL\n",
501 "dtxyJVSDUGquhIZxEaaEejSussD9Udd808j2W8HplsfepVMmE3NitdicGLQn1tgwod04MXHoCxOe\n",
502 "7xz6e23OeydqKw/tUmMWOzBmrzgNfUizvI9hyCrfBoQhk9f7twGRqYp/2L/QD+e12z9NhITftcVH\n",
503 "6bEcJMYlVXbOjgl0Rp+yHMwJSJ+SdvyqCZ8ya/IB/86ZjcPF+g4z9llIc7feRxfrnMm1vcNv4+3c\n",
504 "jHY+KtuZO3l9cFsQrz0HiziuV0LDoYWhlSHfFngqatBOkvUkb3NpApzn0iPGdfg3aCUjfWza8bGm\n",
505 "XOO7Hh2ORx/w7fQ95/uB73UfhxVcN25EfRXfsG+hb6XPv6W90sb4rk/Lmumd6efSP0i/nn47fTiN\n",
506 "mno0XUkPpxemfVvc2ID/l2r/c8bYr5d9DbtjFxhVezMImBA4TC1fSC1fTwXf6Zw5vlUTkcP/on0Z\n",
507 "rE2Iv2mFhuW8J18PvQ0X1UrslZY3BD/IJT/av20pV4ak2LhY2biwpZWzw8rKyQWj9g1cNbKlvaNV\n",
508 "6wXS7YvJvetINnEsB0CmQoFsoDfg3dK+hSHMLQwH7kGYOfVM/MX4q3Eo+BNxWoML+daFfGsr693m\n",
509 "1ms/DTI/nZb+CEIqk4junnPCYyM9swvhicTwacet+IR559DcyuyFNe2N9w51nfqh3lNXuHp2HeYf\n",
510 "0f5HyxymOp1MZP+K5DDJn5NsJhkHS6lnCDHPhDud/Ib3r7gO+T261rWMvu/xUmhS3qZ3nnepF7HR\n",
511 "P3l/zhpfZI1fkwhUa/n2Tp7v+zQ1IuVr+qCqf6BkjlFGl5J4QcajN/ju8D3oa/l2+6Z9+yAyLVPi\n",
512 "wDWIwN72z8i28wOfDnwxAPb8L/LkX0m8AHnqjsCDgRbvT/OW3whw9XQZjX+vf4EfpvtW/93UvEfJ\n",
513 "z2+B0JBEptsVimHL/sBM5CjdNHBhBJyLIC6CEnyv4bg4fW97KVMHv9DZdQ9xf4qdcRDtFEkiRNXR\n",
514 "2j+hwf4Vyd+TfIdc+g758Sbrf48kxPovMkTZG2Lw/LLnTQ9G/12/W4vpTGLOHG2OpjW0RiNGe6Hp\n",
515 "2ocvOvRV7dpLDj1saBMT2p3anEPPHfq89slDf64+4pHYa7/FhV8cd2ze4NlL4xcc/oD8QHKCQaLo\n",
516 "pALo7pRDl08w+pc65bRrib9GE60omqbowD770LqYbvnYQdtGxNuK2k6CAlz1vaTGtIDxg4LJ3iz0\n",
517 "ZpnHsnobfV1FY5QP1zZurA9fEb4+vC38QNgPSQurtVrY7bbQiMDU82KP2C+862Dad3lwO6RrBMYr\n",
518 "QjI2UpGSIa8mbzHugl+HxZ+fCjJOmhecNx8zfOUVzvGMMya0S55d9uzPFu9ftmyZdo/LR2+eOuTJ\n",
519 "t4MhROcrGdeupBkSoaDqAdFbex/BvYFkFUkLRHJE29teyAmtJ5G+/FUQGB6ueT3H+ELu+2xzcySp\n",
520 "B5G97T00AFMkZ5KMkEQ7aQTzHynN7etJHiCZJhn/YAkP4SIk5ThCPrQ/RQv2TyRnMxobE8sQjU2e\n",
521 "LM4UUNm/4v19JLtp4yLINKc5YN902x+K8PXvQzInv+y/j4r2WUrpkyR7qZG67GDyy/p9Olr8vr5X\n",
522 "Zx0G3U/qat7GdHuNrZbtnmInF5Mp2zWuuWovalzN4o0nSG5Ci5M/CrwBOz95QeAq/Ew9EvhW4LvU\n",
523 "/7uCNEhTweeDe4L7gz5EkLRjj5Fsoj7tcNOAcf2Z0IuhV0MHQ6j0uM5lGf1VjGrqEv06/Xbd62Tu\n",
524 "vyR5hGy+kOQukudJ9pOcE6GRfpDjvZPkRyRTJPtBmglGDw1qKBVU+x9vXz7hOSy64c4mLr/JM/7e\n",
525 "iZ6N790nj+84dvkJxj9aue3VIVNVWthVTLlu8N5BqzrtyhAjfQ8kwj8NRR2PrfSv91/hZ7DBmOA5\n",
526 "f2hLS0ccjwoGIqbh8cSIMW6sMjYYm40bjDuMB42WoW9hKr6F30JsmVxlbWDMdD1czBTjp19bmH6r\n",
527 "EzxJ2/e+3Q3hp+2bukBcJW6GnrX/gBmPW7rIiT5xnFgh1orAlvZXeNN4EO3sFtNin/BLw+uZRljN\n",
528 "vZGpHwReD7wN3MatSwLXBW4P3Bt4IvBsILCu/W8BtuYPpALNwLzA0sDZgcCWlp8rGiOzm3MYlimm\n",
529 "ejZ4Js49dC7IZZ41YOjH33tI2jonF3+C+4KiqvYFNQsxQ7l9PfRpknk/pjxuyg1B7uwc7pMhgoc5\n",
530 "kTeOnCgherTftMowSnvbgjtCmwnsuJDr2bvCMuvelUSyNN4LHrb6dnNPaCGb2tfHvc0+u6/a53UC\n",
531 "vQbY1nB5KDcD6Uwa9i6/Jjf9oipemKBHANnSPo5n20kOMrbXPTkPlHABJeAAyQqS7Z21MGbm7f+Q\n",
532 "Z3SoaUY+1IUpqsE7QeCTDjIVCi5nvDRGLXiUZD+jn0AoHeJuDW88RbKc1mwZjc+jJPtJ0hSXp3i2\n",
533 "nDIzZi2jzNxFmdlj7bfegcxMBqw0A/F3qBtpbgzn6F8XcBFtBcl2bvq+GjsY+0MMtfVYLobaE4xn\n",
534 "QDBnnh0kyfFyNdfYbiVZzcz8VpK1zFy2cpl5LclWpi9rJeHyyGrmK7eSrGaGems30SVPJxd4J6BB\n",
535 "kwuCE5j/5Hxzuckfa7nFn9jyGH/iy+OedZpcg52x3CpDKzfPKXs832GC4yY6/P0IMxw30+Gv9gkm\n",
536 "OW6yw18mOW6yg1+1xrMQPuRG+hDR0FbBMLcKeyd3Fp7jNtnbmKVc14nYuxJQ4+g07W1yr9r83paU\n",
537 "eyLt62MyNW/Vp5GBj+sLmyub65tXNGHPtjVd3a1B1Gqu3KVwkaLc1eRGJP1yCiLMhdbptl1L0W/Z\n",
538 "w7tiShb3UJqWM+y7yPsZMm++bznzi7tl7Ea7KDPNu0lkfvkYV03WSMKlmR1yC4BLJ0+XicM1bO8V\n",
539 "kt+ThCixUoov7qwfbSc5hWQZ25+vu+0vZfty/+6AlAJ28jjJQRK5JrTf7am9AkRzMPTNmZNwli5d\n",
540 "EHHqCR239OrVs8O5gaUbFi2f0PKH9mujhxZd+ufr+k7+5JeWa9869BPPjc0Vn1yeOmHhwtkVbeXi\n",
541 "Q/+6eMmmLxy39uY1A1zrlDZC5iN1lZNpfcyl2pt7wa71vVf00rb0chdZ7p7v5P7xepqJt3sP89l6\n",
542 "3ljofILwAe19VLY33r6C5mQVv0XYPICW7YHqgGfL1O6B6YF9A9Dp8UF+kaE2pllpIfdN3h5Ql0e3\n",
543 "fXGn7Y2y7S6Ob93keO+qXuggx90e5+bI+NxVc3nj+D86tuvl+wva4+hx8sGB1gCcphjg0JDOTA/I\n",
544 "+TpDwHwHDg941HDk6GQS5u3YWENkxBz/1nahjzGUnGwfQsQ+Z6GpNbq3PTLKmG+U4yMRvNwsz5qj\n",
545 "jCleEj/hmtFlNM7XkjxDC92n1rEMWaf9Y4rPfpKrQPi9Rtfe1qjdmrO3bXbNYY2rXDs3+V3zZXqG\n",
546 "T/DGPm5dby7cQJ1s0fKMcIVnFQgXXmn7M+r1VyiVnyWRS5j7SbLq0XXcQZvKPs8l43+mtDbU/a1c\n",
547 "DjpAspGkW430Rdqtq0hmqxuXzGZ7s+lQ5tnzqvPA44XcJmzN281twn3zXE2fBeWe5Wr6KC5Gj13j\n",
548 "lRdduOjixSy1KFeVvgeZDL9JmHxavEBmXkI+XkPyBokR9XIoL5OBt5BcSfIzElM9+h65tdV0lfRq\n",
549 "ko0kGdlu+1Uy5DqSZ47wZxaXmSefyn6PrPm5ZE11Fmt/iQw5SHKBZI26+8IR1sg3FWt+PlsFjQs4\n",
550 "0BUMW7eLxzmHAwwVT2EA2a8dr0Gk5zGpkkuDexioOquCQX8G+WH7akapexhYzg8s5wLCvDBqd4NM\n",
551 "PhZ+iouDTS5FPcU5L+XE/oJkzFkJXDf5qDlFqemmk1xAMs864iSXcTHqMSbwb5EEeXm86xknD8R+\n",
552 "z08Qsvw0SnrJV0mO4yWz/PbvSbJxrrzHV8Q9joc8TjrMBMhWesjHSf5A0p/m0mPGtcdvkfyeJMSV\n",
553 "7WVcUv8FV7abXEOXS+pyIb3JhfRz6hjPssbqBnr5PVnfz88u3uFKZaCZboJPY/zcYjlJoBvkGcLx\n",
554 "JMkabulme/iBEs/WUOG3khwg6ad1WsO93P5BJv0jnPwIxYkYZudws2DOxByuDMzBDR032v1zaNxu\n",
555 "Jq5yUXSC5DgivECbYEbwOME9qP2B57rGJvwTzD10Ap1n8r8gMEEsZ8I4RQR7ieXZBE8GORK1+YTx\n",
556 "bvMxwng2YVpKBB+1pojgft4I8IaKGdoX8UaaGP2YaP07yV8Ql38jSREtFU+0byMoa4mHnwA8SnPw\n",
557 "VvbfKfMSjK3k/lb6rbVlcr++uo5H87lX/pbcMCcOEoztIJOhZpY4/IFBzg4yPtTB4fdk/FqSHHE4\n",
558 "p/Mdw1skq8n9/SS3cjt9WQeCU0Amb579F7M9R5Z50/yjMs7XWD3znQ+v6t093Jrudpd852c867o+\n",
559 "fjxjoEat0TkbnTXKSGjpNcOnNU9zzj8zclrTc3q1wWDouE19Tefsov6x2Td+mFHRQPfp9TOc8/6e\n",
560 "0+sdv/PRjt/5R+l3CuOGvbS6dGTp+NJVS/0QkPX8WOHw0iN7Z4z7M3JfOqPV2rEMPIudgcXO2PIr\n",
561 "UTHdXsjAKaZ2pZ/jhwwLcyv5IQN3rj8gTZYbZkx5UpE0Q6TUcPt17gHfAMIlkRnb1Ecim16SFzuh\n",
562 "+SWd3bJNDG96GaRfy7OD7m6Zyk97GXkfZFB+QP8909GQntV7dVj9axkMvUhyK1P6W+T6YDfb/rFX\n",
563 "GlqcXc3GLiK5lo31sbFLeHYN3+vTIZU/0X/B3LvAxapbbK4izdyM5rewXE7aceXIyb3xeO/JI1dO\n",
564 "/MNln//8ZbdMaF9K1obyuaF6YvHH169ff+gp8noEznwAfjwl+rTX2nYAvJYrr6uYfxzmOIdp5xIB\n",
565 "W8aWdiu1txUADghtbXtX1fvuZGtgNwMEMeAuiR+VbbpL4rsKYHOCy/+7morTa+UaJKe6lROUn8xt\n",
566 "5SzXkqymet5Kspq5yEEujDxPHf2Wq57tR3nWzTO5v7+C5FF+ITeWXUbl3E+bmabKnuMYTmQ7OWY7\n",
567 "uf25d3LMdnLpnGfL5PLcOfhpp/Pg7qvFg0W8+2Pq9Aska2hlV/Bse4nWqvQHfoek4+7kRHlNGa8f\n",
568 "V15Rhh96tXwQP+013DiaqPMl2uKD9T/QGuTkjY4NeLVxEBZ6Um/kGug4RxudphVYRt2/q4dj7Nnf\n",
569 "804Px9iT7kGdc2gQljHI20+SZii6vPcchH6i/T3yRXqa/UypfkzyFY74RyRvkjwPUqvNyILk95hz\n",
570 "NCdHmufkTN6BQ5d++IsbxsY2fPHDp+F35Tl73juze2LT4kWbJrrxu2gxfsfOu3nlypvPG+Pvhu2z\n",
571 "PFrfCZeeMXv2GZee4Py6Ony81OG8diG0kf/zii27LLWWGJHrwc9RzihsuxKQpoDdyk63ssPtP9C+\n",
572 "hrLZrGdLK7e3naeJ/SZ1fGVuPXRc/Wxpv0s4TT48nqQPREpl1m5l9rZvgLkej41nVmU2ZDZnbsjc\n",
573 "kXkw08qEtrRX8mvaneTQwiK/qChuK7pfVMgdAVdu5Rqm2h6wnBViWxoJrhnkudUud9Wzclc9T9U9\n",
574 "wG2ji0PXcqf8dgpznhoql5+66WbGKKkX8MPaq5O38AvO5SkqPHdQLDW83ZnpzL5MAAbAzZZF+0DI\n",
575 "tQWyzUtJDrDNiwj6VjQ31Z86PnVKyrtlhiHgwor6LD7R8DZ23ODaghsmfnLZ59et+f6av73miDV4\n",
576 "7wue73x8/SkXhA61NLm/MHr4X7T/gE0Y8TzQjvR6B1q9dmtkb3snfc1hkitIXifZNkIL6n8XVXYF\n",
577 "YYz5HTnhTe9t/wAz25XxS+NawaOVDPmvINk26lrpIXB5yGV5AhcJyfKhhMPyIbX0G1Y3wsPtTGKI\n",
578 "Z5lhfpNEGMJ2q7F33NjZeK7xg8brjbcbfhlMbu0kE9vlAtaT4q/F34mfil8K/7r2e7y/yV2elOuS\n",
579 "k89qLzEKeZWB5TJ9NS2sTF5Xd9ZQHqExesPmd9j21bbH+QZ1D2G4h87k8RTXJJ9NvZT6SeoXKd+6\n",
580 "qQuzV2dvyXJp7NEs04c92f3Zd7KA10eBZYY9uaA2UfNwJbP2Yu3V2sGab93kpu5r+P3rq4wHXqE5\n",
581 "+AmTqq39FK7+a/mp3cF+eiKSixkWHJRf3vGzuX8HmXpk5Fsj3x1BavnmCOXndwy3psTzDKi5pKk4\n",
582 "w53pqae072k/5lb0L8mFPXKvQ3dnew7JDhnxcsqb7Gsw5XFjR+rp1AupV1IHUn7nc+Pf0cpenSWT\n",
583 "j0wTDy+Sn26SBHNunLqgRhY9XXuh9krtACbbXsE1n2s41YtJftKZ9B5O+mXO8UKSt+QZJ/pjd6Lt\n",
584 "x0a4q+2uErjxjbulNndWwI1ytJ3D5xbHBvJjq9avGus7+cz+RVf1LcqcsaAwNlCszFm0dNGcSs+i\n",
585 "MwZO/ES/Z+XSaGV2bWRevTB0yvjIh+cWZy8Y7hmO1UYqzdm1dLo4sGj2nNNGs90jMq+WeiLz6iEZ\n",
586 "35zz/zH2JvBtXdeZ+FuwcwMJYuUCkCAAghQJkCABQqJIiBJJUCtta7cZsrUtWf05lZjEizLJSP80\n",
587 "sSVPMtK0iSylnUj/NNqcTgU+w9DSzkitLWpJfyMktTYbrdjakiU5E6mNrcWVybnfeXggKSnTOtHB\n",
588 "e49vue++e88963e4nzD5poqUW6ZCQzC+BdKJQT8ItZcRknLI3yIEGX/Ucs+8rVUJqvqEQNEisqvs\n",
589 "HL7DIEgnmMju7O6wtBlbRr2y1KrYlFE9EkWikhVDLeNNVYwVtFaZ3fzc+P8Rqv+P8J2urodlrAru\n",
590 "TqKC8We2oiH1Bvy5Asu81InP62RMSglQKkpLuxEPvQnkOIK+O51LnMLjJK5ytlOOuVxWDs9Coiyg\n",
591 "WMYoiDBQBrcVm9lFheX4c1FA2sZW+JF8WTS4kbUnDUvrFAkr+YLuVXBW4odyPJ8pO8A46RrOfznn\n",
592 "kST56YUc47wJMlOnyAl03VbbQ1F85skoIDMTnso7mquqmjvKvxGP75mxMOJyRRbO2BO/pbE319c3\n",
593 "2TX/+GfWQG8w2Bu0/g/2LZdO/EZYzfqygh9E3MMSJe5hJB8GfGOiPEPpLtK57LIzLN3CFq1Cg9jF\n",
594 "UjRSoXqQ3FC5GaLEbuchxNJ3UpoLyDmQfkgWLqfy7fNZF+c/bNQnW2A+eyTWpeQ+IQWvY0QxQqf2\n",
595 "iSlxVGRSRUTsnbSmpg5qj2rPwMRMxuSDuqPo6R3sgySvFd1BNpOmyFLkLWIy7PIiJne8ZtwB/ncV\n",
596 "rG8HFGBLsRd2YAtWuFomqUu7sIDdALFjdwvYwC6s63abn63ryRv2+2wpT+ntdrvfzm67yg5N0Qs/\n",
597 "GMnGtGBSSoQH139izX5qXrHlwmNeqWIfUMU2hdXmmc8v6X9upjleWuX3ewsLgBpSGud1M55dGoks\n",
598 "fXYG/9fjC0N9zRVGtdpY0dwX4pOYv/TdaP42ZeMykHdUySVvVU5AlOuETjcItfpQdkvOsXr4OjkX\n",
599 "rCF5qPI4LluCKzZU5xKVboEcAukEuxusUnK/5Pusy91Hzv2aGSvaXYlbnau8UomWaJVbohFL6rBV\n",
600 "R2EXwUPB48FzwSvBW8GJoPbxbduUfSfpkCv7bGpF8lbVRJVAB8CQ+IkvGT9YQ/zo7tsoIl8vcWoV\n",
601 "pqaK3KAxWJET4gk4scgbGoTIk4sPGBFExJ2CdXVCcSgCWQL5bhvIOQh5EA+CmIUxzEcXuFkRyDaw\n",
602 "tD0gG+DEG9Pf1isshXzHyhAnXkfigQr+2eRT3LNY1JbBsdML8jJWtu9ivftj7qccllXFaaWiNAiB\n",
603 "ZDXSOJar8XWu4oLlIMjc8YRMId7Nh/hG4fri8V/Hx3/bL3ukyD8Oo2eCbRYJ+ZLI5GTpCibVcUbA\n",
604 "uAsyUhFsC3KArnSOoloLwNDYS3MF+TB23aNoMJDXQUbJEYsOhIs5uV3cw/oWbnxdBt00kNyg24xp\n",
605 "eIJtj+jZbVR6cvGeZu1PtaniqpUqNmG34G3ugmjB+XyMwBerZUsIPKa9WtkNIRkEWPlSKw0vGF41\n",
606 "iAMQXQszUhyq1QlGRorYOXsw8wYx85Zg5lGS3zaQEyBjxY8NXSQuRF8ln+yI31NsPNJ7IP8MopL/\n",
607 "9F00cxYImilHTPyzinyhiCdgXEuflgwiddZN+Ax+QSFwjKTMBo+h1SAO49Qi+ox3cWMrPjtZleIQ\n",
608 "YXQILriD76KBA+4TdO79XJx5BA8lJ0UbRJ17uTANCvEhh9o9WlwwFGeB3MPzdTAj3sUHjYNEQWxF\n",
609 "YFd4eoQNGvxPdNP/Ql8I0nJJOND/y6WSIC39Zf8a8md+ZYpfk40lDZtrG+AnFo6Qnzh5SH8cAudx\n",
610 "TIdbmASb9Ntw4E204r9heJwQ05h6nB49KQd7yGEob4HsBAmyd07wmVjRNn43f4g/zp/jr/C3eO1A\n",
611 "zNTJL+EH+fX8Jl75m569E7pMy/PUqaqM1I+uuYTQrwJOZVS5VEFVTNWv0gxL2/GR1JlY8aSD+pz6\n",
612 "ivqWWjcQMyN27WH3tWFY0sgt1WM8x/KUoLRBnZpJM+jlQZCLOiQoZWKmoDam7dcOaTdoN2u3a/do\n",
613 "E1o9womy2ye0ae2YVjuAuxkysj+pE5/lArb2InQkj7Vu0jd+Ii+dN5bHWmc15rnyHvWd5w3Lgefw\n",
614 "l0tLEHR4q2ACE9cJw24aR4OPd55PBg7lgQlJpRiB58Fz1nAvgx3tx2i8A6LBn1pBvpezw8ObDomA\n",
615 "T0saLbzvUh/jlMkPNZ/CyvlzWK+Pac5i2w8OuoLCozhNNhxFnZb0tIMJ0IvB3oOBfXj6OF+Bca5H\n",
616 "9HavegUs42RN1cB5HNeu1LIDGnDhVSB3MMA0GHZtIEcp1QFb5G+J52GYezjEz3LLEUJiQ6ueZoRn\n",
617 "Q553i6KbF0N8++jq27xq8NLl1bx46/f4g3zZeGL8+/yc8eP8N/h+GvMT/8rG/EI25nV8YUIISOfA\n",
618 "ONm6sg2xECqMABpsQ6oNKiWITP+4gDKBoiIktSAHATFFH4GkGnaDTs0SzaBmvWaTZptmt+aQ5rgG\n",
619 "N1C25TAFtpLuxpAZBDmX3RoGHgVblUA2G5Sv/ljJWlKrEJgtdaNHl6mxCH9P/SP1XvU76pPq8+qr\n",
620 "avaApWqEy4Gj4St9gkmFeEGOqUfqlHpUfUF9Ta2W45qlN9ktmITOh0xs6WEi+vjd1X//96vH7/JN\n",
621 "/J+MS/zi8a9SnCb1Ha3p0aycsp/yMvAaTFjRT4BXdOZ0hEOK8pCNvcxevy53/XN0fTDLdlJX9LgF\n",
622 "EwqL9E49E84OmY+bcdh8yzxhxmGz0yzIgZw8Z2X3MiPWnbcwCYGtg+vBRwN4myXYWoLXVyOJhX1T\n",
623 "Psb380P8Bn4zv53fwyd4+qbZ7RN8mh9j7AmahZBGDC8i5f/DXxIPoXA3aQM+ZD9IEGQMC8Z2wx5D\n",
624 "gi100hUM5AkQJ8RySqufjMKn+KmHg+QQPaol57qkzQkXPhDMa4rcQZZNWl447CBxECwm7JvziD/j\n",
625 "q1qrhKLxZ/k/Hxf4n4y/wP+rsOXLY13tQk+XHNtC/UjftH2K7uiltkkb8kh4xIjszI1XRM0BJkWJ\n",
626 "cfmM/1/8GGfkWvh/kSoDYn0iYBxRs7kxATHRyQRGBLmUqB8kjGn2p4Q1nbAGpFtMkkaatDstBZEu\n",
627 "dyWM7glPS3I3PJTkPhn+ginQIme7twSS6ZaxFmFghBMeJOqMSu57qfBAssinWNjjLIyjBS0xC3w4\n",
628 "dS0Q2z70fuoVyEbzEha2i+InUETe0Z5EWMsdCC3Eqi4WfAKGvAXK2veQuPuO+SQblckd5n3I36UU\n",
629 "rosgv4V35im4zE7ClJansVgsXkvY0mNRs7tYPsGj4dxN7ijbB/1zH7SuN8lOCkPqZbhSboLUBvnh\n",
630 "1NbgruBBWE/s8K7YmnCoaVfTwSZ2yM/2kkeaTzezyeFvjjb3NYvD2aCI67kwHnqDD7CCfApC7f8c\n",
631 "7YSNKAnDCRJpcGCFBeZmyw008IJVaRSy6KUbcOxfbrjRIGT9a1Y8OtU8yh4tWZr5Yc+U+JbZYou7\n",
632 "WusLkwILx4/b6211T4nt55+0L+huMrl8pTWtNcWvPjm7tuu71Z2N5WoxJopCxZKoc2ZD2axVz9fd\n",
633 "UJtq3dYqs97mjzirw/kbI4F5pf6O+l+WzTIV15oC/mJ3qDo6x6Uj3w4bf8J7bPx2ZHnS99nAtklc\n",
634 "mPVbMAxtIXwizJq7PTwlDmH6NU/TNW6Ji+IaJGv2Y+tEFPJwdE8UWWK3WyfjvmcJLdwXFKu/FGtI\n",
635 "ERN4kseFc0zFBbvRK1KOajglizpMzuUysl2FsR0RIjZUmLQ4JmoHuG8xtm5jclSySHAKFDzqjoRe\n",
636 "nvXc00LLdm5Ke4/l2vsctbdG2gb3/ZXWW3Df0ywKIlt0Wy+O9t7qFSZjJD4Ta9gcNXBl3FKxTXoq\n",
637 "zPhl7Ck2A58ywmgqDWL2tYefwmxpD4wY2GQNG0eMqgeJdmOijNIZytPs5ERtOlEbSPgyUmM7TpZW\n",
638 "NbKbhI2J7nSiOxAr7u8e6t7Qvbl7e/ee7kT3iW7dQGJeJrlnXmIea+GC7CULMAhB9iOBe9vy3cux\n",
639 "aiyHLrac9frYcoUJLGZTfbHCBOJsJ67sNLGdJoUj1LOdeuwsZnyHzfr2xU3yeyQ725e0s6nqbA+0\n",
640 "C8MJQzrRZBwxC3ipkTL2w16p3jhSzS7xLa7P4ig01i9GI3+NtOAP8XJx40gXO2NenG46L5AMzovR\n",
641 "29Al0s/wIssYSb234P0FHy9g0/OPF8hxBCshDK+FeHkS5p4UyDHYHg47T8GqsgaK8CjIVgIdANkI\n",
642 "w+MukKRfYQpkabyEnONPQW5E2MPeiPw48laEPexSG3jN1rZdbQfbjradaWMr+gEM4NMgx0BOImWY\n",
643 "ErTXgrwOchIZxDtAXge5BMfnpR7IsEisPwxyeiHYCchlkAv9uAHIJ/3glk988gRmBb3jOiJ40STe\n",
644 "cRQkCUYyCnISNpfDICmYHk4RwVvvxQu/BvIjvPArIEf8kwznBt77Q2RgX2q5juz21yI7Ivvw0p+w\n",
645 "LpB+xt5ceh/kHaRav9a2ow35TziQxHt/D2Qv9QDIVuRVv8BePrll3k72AZPnu692s58LPdd62HXv\n",
646 "4J3fw5tepdddiIzy/mv9MC89gQOM5AL6tFO4XmtraDKfGszO65vC8kKtSLnOogNRmjZ4o/DPpd7W\n",
647 "qsqQ1/ILc6PXThxxpt/SZXKHXJUN1Y68Fu/aSOuQw/3sfLDEuq4nfOv5cm9twVOz/NWD0fDSYutA\n",
648 "qGVJuIwvrIrUWqy1EVdYZ3LaiGXWzXTr9a6Z9Y58c3mRv6mxJdreBH4ZiDoNFZ5AmaEt6Kpp8dYF\n",
649 "azqXN1U+lh9uIv5SnnS1BduYsB1En3JtSI5o29OWaBOnxF4JCeECV8Q5uW7x39hMTIQyieqMdALh\n",
650 "BlyoGjPkc+gbH0FgYZNNzdT7Ivn4n8KTehNkKyOJkDExOyNtmM0PEN8JkYtdOuBgf6o2JqoysYKv\n",
651 "V/1R1Z9U/XnV21XvVmmYOgIT0hcwZH0E8iuQIZAySxXu/yrsuztB1oK46Ghy1HUB0DVuuQ2RHG5N\n",
652 "UD7wFnxJoyBd8l1OdmFpB5krH7iE+bMT5A6IZi6Tb2YzBpihyAGpn5GReewtO3sVNtbG+FObItt5\n",
653 "2Y5X4VyU7UhKnLcNjUOwMzAJ0GNkV4DKk/AakTgtaSGFuelEKYomXwaZ2+bFgffRls9B1KxB0kvY\n",
654 "+iHI34IUuefipDfR2VfR2W3GERO75V5k8JXJd3gOnfQyyA9B3kW82q/K/hmSimuumyKvMGlfRw8H\n",
655 "uTIc6CojJeQueof6aR7dijFJsL/XoNYfJr8WwmbXaF+GYNUKNvG5DvhAujW6l3VsNpMW2Kuo4VNi\n",
656 "v85QKBikl1UgFL30Y5A7iF19E7LLXZAtIF641ntBTsIhexiEhsANkJsQaXqRl3gdfPUF8NWDIGcU\n",
657 "sSv5QuOrAIQ4CM5/BuQGyLFJKA4ssEdBDgPJYe8sjBSQwyDaTsjmRGJoCIhvDiM350KE3pLLzvgE\n",
658 "zPIlCGcX8LZ3QLTogdFcfPTrIO9QNhfIfQrdgr92q3kXpLYvcu/bA3IKr/ox3vIlkI/wquTh78P7\n",
659 "3iA5Di+9F6+6BmQU5BO89JrGl9lLp/Y1phpHG2F3x+uuIa8W3nTfLCxXs07NQqQBXs5PBC/XB+LH\n",
660 "G37E3tBUKOa4oEiIaNi1dogmq3sKP8yF/MguDq01Ehp3N1UW2mpbKioC/ppiX9TfMLvYateXNvrs\n",
661 "m3aveW7Gc/EZT8yucTTMdLlCZcGY190RKCtvaCv78997gn+m1O2bUVbZ7C41lnst/O66UFuwxFdd\n",
662 "oc23u+rGt/zsheicspYFQV8sVFtU/VRTbUe9xVw7y+eONLgLDxyYKlvdyPG+vyXe94bEzYIsiE+7\n",
663 "CSSI3RPoju2z9qA7NkHU2oNVI7hAJsMSB3ICu9uBRyO5OnCPDrAFtpUc67jdAdsZtrd37GHbybGe\n",
664 "21h9uB54akBcPfhjzx4cDfbINnGunzcJ85m8qeFek3iOaVg87G5JlxCEyClmpN9C4ldxPHmrobwm\n",
665 "A5pOjQBjmfQA2jAMudykCQHcSJ1JiGl2EbInYvq/Vv2dKqP6tUo1IH1GWZdTTW9DKi3lm93F2L2n\n",
666 "YSthyEQ2l9bg1Y7jxzuE98aX8OvG34RsvIr7VJjDf53zcF8yZpcwZSD6mgAkIMfJILQNbfRkpB8r\n",
667 "Yg/2fRkuoQ4kCjLQp0vSiRK2bRyxCQQj4RIonoIieVlDYvp3hJMCUtlUAzH9YfGUCO2NNX0nLA47\n",
668 "DeTczbqHccYRy2nLJct1CzsD0W6xAoPH4anzzPTM96z2aIa5mP6ocEa4zEYBzj4qnhEvizdwP4AK\n",
669 "JHcaDhhgxE+ZR80XzNfoju9YTlrOW67ijvdwxzwE09V62jxxj3oYwFLDvAzB5JPj4LS+DhGjPhsL\n",
670 "FxHm5JVV+W1Gi8VRYg+XF1c6TNq6Rw/xcWNVWTGvyTcUVhVZ7Yba6bvobyc/xP93ysEchem7nqwY\n",
671 "mVRQiAn9gjic3CBshuvtNtCP8mG2TCLXjc35TsMSw6BBHJZEA/A5krPEBQBjQAgY7qHKSFdkc6vU\n",
672 "DKPCv2IY1WBrN7b+AWQudp8EKQHhyL6XT4vCZQ3l0cHoqu/XDengRGCd1a9DLl9GqkN+2wNwwdlQ\n",
673 "sou0TtgDF+Lo0yC/wp+2g+ipddI/5DAeWmBauk1IHY/momkzSiLvElz8JghHaFNs4CfhgoGOlkaO\n",
674 "oJCRzLDOU2bMN0Ei2P0cWypsQY3OWjt76c3oPtKPYQv9TyB4R2mZhr0RU+0MBJCSR9AZ+WRyO0wW\n",
675 "cZhSj2hOayAtU4L9aZBjlJODPFRkKZ3ViAOpg4ajhjMGccAUsWqtWsRH+iLW1tCD75t/sDr4zDPB\n",
676 "1T8wf79daG1oa9hY861v1WxkG9s4gatnMtjnTAZbyH1FvU5qqWMjoM6YmJuRtmHln5iLr5mRbisJ\n",
677 "R9J2SGI8Ywu8/J3bM9LediazqJkaGGhhr7mHKRmJFuNIgZrMKQicaTEmXOmEKyBthwgwxMiIk52+\n",
678 "kGtHhyxqJ5CIucaRFezgAB1MLhkaHGJfYfeQ8okC7BMFFCmIiaEjHkhBAWMinpHScdwW5HYcrQJ0\n",
679 "HkLrY5lEND2iY5M/QAzkNvKauRJjiatEBHAiHNoTbLlLFZU7ywPlbCw7PQG0xRmQhqBntMfiaOGC\n",
680 "eAxHmSr3JLtXzDiyWpDzUmDJuk8E1q7TcDQfLDpahLAXDLD7IKvgDF6NLQO2PsUW8gslHcVdg9zH\n",
681 "7o9BzoKU4ZgVAdWfQ1DZh6X7ldLXSxEjXmotZQOdsA1PYhknk8wamGT2mVNY3DUIxgqDvKKYlpIn\n",
682 "7efhpVbbzXYPvNRrEIW2z55CpOkrWP3fBDkJae5zkDUg+xxgg4DP8zrCDtVw8nXHmw5EFOKPZmQf\n",
683 "7IO40IOtNrh1v4C97h1I7oCQk/oAqtVWG6+Fe35GfAY6BTG/KyE8XAfpAyEVdSZIaTObyWuaX4Zt\n",
684 "6HVEmphb2V3fh2lhB8h+kPNQ3faDLO9At3S8jiXxNBbTPpDLIFEIk2dAbnYBjaK7rxtiDxOtkwd6\n",
685 "jmBptGGZjPb0YfsLKK5tvbgDSLgPEg7IfkZS5+dfnf/5fCbajGKt7gXZD3JsCZq8DF6TZWghyCiI\n",
686 "dSU79tkqtpUCWf4MlMtndjyDvn4Gr/4MlvYPMGpWYixcBzkKosf4oOFyFruUsRYFWZ0bHwbs7sLX\n",
687 "95cyfeoPSr9Z+kYpa5wDKCkzQfJBCEnxMkgUI+Gb2PpTkHzs/ghf+3OQl0HWKvJuSmu32n0YID/K\n",
688 "DYVuxJK+7HgNX55AFTXAGAmDrKWTMAa6MQZaMQa8IEcwBrq96GFfnw8KCYZCtLYPQyEyoxdD4SKG\n",
689 "wnmIkOGGHmjr1zAEVoC8jG8P46C0Fls0FKwYCltgjftx+C1Y4z7AYDiIcfAByCoISRtB3uhQhsJZ\n",
690 "EMKYO92lDIobIL1QtLrx1d8B2QdyB8QCCSrSg0b19vSyp/wMw6AV5Cq+eQ/IPpALIHdAjmIc3FwK\n",
691 "Vo2vb8OIMGMI3MXX/whffAvIRpBdIKufgQAkapiIa5kas6pAmoSmgi9mY3mqvT6yhOYi3kNaXAWp\n",
692 "me4hBNuWqtT5eY5wfXlwyfMtc762rLl52dfmLNjq77TNe3KgadGWNbNmrdmyqPtbA+FAd391ZY1K\n",
693 "sM6cEVtc1bG81TPbyO5lqTDWdDTYW/1VbXU2wTt+raAsT5fvmb24LvqVed7WlV/v6Pj6ytZY1D+n\n",
694 "wRZ9fsvixVuejzY8OTx3zgvzfeVOm/upuS3P9zfVNC42e8qKBH/nAndduD42Pycj/0VORv4lyciV\n",
695 "EoevGoOicAKWyO2te1qxzAX7sr6B+MRnwizhM87ENfIVUlUjW5tkxCmkDDWwhYUtmg3GhDktJaBy\n",
696 "UCBnJ8hgUAkuokTDwqnBXIoNkEI2NQ+r1eVkA4TOXAQHQDnpthdg/YfIBmsOzPT1XkR7JY/Vn0XE\n",
697 "+E3E812ulwFydwkHmbwkQ1MNJHeJB/GzQ7sPyZ47dPuAQrUjfx9yPncU7EPOZ7S4Dzmfu4oPIvdm\n",
698 "FcIWkH2a3FVyEEkbgH1KRip7EaCdco462akp9yiCriM1vTWImkYmruehXFE+VBySJUZzNtLI5za7\n",
699 "+d/aG+f4/fOay8ub5/n9cxrt48u6BOOMYMgaebrL4+l6OmINBWcYha6bwLWtaJ7ny/4KTeN/bKu2\n",
700 "GDxdq1tbV3d5DJZq22KyZasnfsN/lckPIvfThIgMZQgHE4hELeKdvDCc9fFPQGCBoZuwXB4DhaM4\n",
701 "rZQMquQqbh2MGVsp7PUgd5Q7w13mbiDs9U3owW0CjvcJq4R1wkZhq6BmS69wlHV9zI6+XyWuEzeK\n",
702 "W0V8AEUgz2eyEa9VR/nATOFvS7+sN6H9T0z8hvsBG2Mi15hQBRC5mG0tk1ynNFMZQgpAHYHyuJ9o\n",
703 "bxc+e/AF7pM/8RxfLGS4AJ+XmBFIDs3YMEMgZKAZlOKXh42RCjZmS+hQgMm12wK7A4cCxwNMrrUF\n",
704 "KjDQOpswbg0BIFtxBk8WzmUwi/+bJ1DQdoANTBtHcorHOFJDokhMr+ftvJ+P8iq2EBMkFfpHj2Rt\n",
705 "vxAV2NF1kDa/aMBRQ4Ojoa5hZgOg5/SN9kZ/Y7QR1zViZUI4RUyv5a28j4/wOEUjWASvEMZNSIMj\n",
706 "FJh1MAncpdvpG+wN/oYou510r5EO5O5pag63yoZMMw1P0trNlaKZBioOMkYHnOX86khJpc8caysx\n",
707 "6wVzRaVeX1lhFvTmkraY2VdZEqnmO2a2Su5gRUF7ka2y8C9qmioKeIEvqGiq+YvCSltRe0FF0C21\n",
708 "ziQf/W8nnuPu0bdwsHGVHBTXK+FebHzG9Ju57RyAAFQUsWPIwBNawkRPK1eCTq0gf0UNQZ3NSE/7\n",
709 "JgEPQewE2DcJ8LLHUP4u7ANy0z6I9PlD3SjVCNmgniT6EwlsOLAWfblmsi+1DdYGX0OEPo260dzo\n",
710 "aWzFp7mDTzPtI9/DnXSCDXfy404zQQjWZ60fd1I3mBs8Da34Krg13YLdv9Ha6GuM4NNUa8xynKgM\n",
711 "cU32ldZGsVWOJG1V3HChe//upxH+o5+GzZM57Nt8xL6NlvNBXweuXBoquqB+wAGwRQU0FupZRP+i\n",
712 "L03uYjZQikMfDQ399KfCvgefhcVX5XtVsXu9S/fyJzQBKYboPF5NKRhaWCc4ultg2t2sbNq2sn9V\n",
713 "uNsaMT/8YAuNmatCjM8j3JgzEqdBLBN3HJgjJzRpGELkWwLcMMN9iw0qG7RQYBRldc8UfgJaMTuk\n",
714 "UB+EqRUGpyGAaC8tQBFpmqb4Uf4Cf41nc34/RkjefuGwcEq4KHzCOFhMf0R1WnVJdV2lQoi6+oj6\n",
715 "tPqS+rpaDd2PzgaLky0N08+WDqrIaJG9AAcYm+Vlf0IIRoNwhM9TPdHR8YRqhnam1ztTK7zX2d3d\n",
716 "iYpoFEc9yQe1XE9CBzQmREFOaGSFSksgKxrg5EwJnlO4oobtaGTcP6wA7DR1Rv5wIuvqH7TjP/bi\n",
717 "jeO1479i362PG+F/LpjYul4gGTixnpOK1GI9u2CayNMo9JUHYx5PLFiu/PK/P3WP/XJZ/PTf8n/P\n",
718 "/xNXJXRLVUB/XW9nSrVdDrFZDzt/Ech2GbIyUZxOrXdvcm9zM8H5Fgydg25Em2BrCcimHEBlJXuv\n",
719 "SkVgKGU7pWRtryyVOXPKxQW5GKB9Kml0AZ2wgDEDY2mlDGCQBFSoHCRwDMrzv4H8GmQ9wjAITe8Y\n",
720 "yM0cgOBNzOuwugfpo/thJNmHKY3YMKkVSmYPyD6QA1ASjuW8IF8gveFD46eIaF4PNeFdRDRfKL4G\n",
721 "6aK3eAUCm9+FBW0popuvYes6ZJljIF+AGBB8MB/e/LPWD6zsNn0Q8+/Dkn+s7Cws+QYI+kdhIL4M\n",
722 "ch/EgMDv+SCE50+uuXdh5V+BPv8AW0Xo3/XoVUqJly4p2Soyig6GqnQAr0ngDfvwNgThj4wNKY53\n",
723 "6StGwmDxTYhI+RCRKLxzJd7kJoSlG5b7EM7oXQ5DJblLuiladTiXSnYXiVInXedztQeeQgtPooVX\n",
724 "QdTYvVglYwx6ZWEqwiaOVaPRamSB3GqxWPn/Xjzbx4Qnm40JU77ZxWH3ymD0mTnV1XOeiQZXuvk1\n",
725 "jhq+vLm7tra7uZyvcfj9Pp5nolVrKxOxeN7nl+PIPhJa+AKyyW6SOJ6N2U0E2garCllnpVu0gA8K\n",
726 "64VNwjZBNZADcVLxXM5OK40BnUbfrxnSbNBs1qjI3nYLEta3mNxiI0EMF04gRKVIdGId3IDgOhVP\n",
727 "YY3qNKapj8l/oT39X+166qkuoWX7iy/K2Ow0p7r4L2Rs9hPQ2LYzAvGlIy1pazpkbE8Fpn0KQjsy\n",
728 "pyoyWZx26U9hGHgLcuzRyjOVAgG0tzIhvtKY6GKthQd5cJ4y5Qh/XZlyXWyn6yH89a4s/nqXjL+e\n",
729 "DDbEmP4ImIUgm4FdxpGZbAbO7iIY9tlsBs5eMptmYBLpOuz1oZ0mz1RfRjbjEfiMzzKSOuI77buE\n",
730 "IhPIS05+2PApu2fyQOORHMb3LwD6HW7ugXViPzLDW6F39uTMEfvg5OwFOdKOMQ1yE+QXtDUb8xvk\n",
731 "r0GuQkm92AFxi5Txk1MMMkcxFM+CTG0p4fOfAklRWhHIKZCPJ7HJ0czraObBxqONsLo0x9HaA1Cg\n",
732 "D4SUhvagjfvJ742WXQXZBzIK8gmadxnN+5QR638EGRxzQvvojHE/+J2w4JFKR2NuvoQfnU26x+OB\n",
733 "L1AZTFPmkf/ReUaYij7un9kMc3KdkraQaYy/Y1QCTsmZmcLm5WGWKMrAzF3Mlq//58uH1v/Ot+vw\n",
734 "P775S2mdXTxxhP8XoZyr5PyCSVIVAU+Z8bqUHC/KBiBQO6UTIPoilQx8nUzrx4BWFtTH8LNdv4f9\n",
735 "JHQkOumNCX86UUp2Yyuh2znSqPJRo3ogv5yVvZzV8FDYL4lEMjDciayZWpchGHJsMrXaCqBlUEsG\n",
736 "tCwjnQPIs9U4UsmudNLj/GSmpqULgdvJ08IlqL6yGpb8QLwJbrMSgIr6I/mn8y/lX8+HB4V8kojE\n",
737 "14OpXyq5ztTcJNAm2c8R02mUC7mHaDM9LKB3YYUs0DqsDp8j4uh1rHBohqVdWJI+LPu0DFeUn0ae\n",
738 "80Ew+BvllEQF5RPuHWEgtUNA6hBCPrJJ2my9QNc+gLiUl68qV81QtasWAgcUGZPSDeBtH8s/m/8B\n",
739 "ILiPUlMJKIM1NXWy5HzJVSBiUijOSbRRjTamsHUX5O9hEvstNVl0mBxuR8gx1/EUmoz6JMlLZdex\n",
740 "iv4Ya9MBNHhyKT0LAi+zJyxPH7MbsjjJ5CGzPMN8WtlLauX7a9qKwq6lDcGmxeGKivDipmDDUle4\n",
741 "qK0m6ArVmEw1IVeT4Lb5vbXC7E61f87SYHDpHL+6c7ZQ6/Xb3IKgcQU73O6OoEvz0Fr0HUmDWNhN\n",
742 "kPo0kOUIZ48tMNwQt4HbDJWJqfe38Mk3o78ENcV0q8nfc4tk0EHVetUm1TbV5IolC8y0BkGIFCEd\n",
743 "JovUTog4E7jLBrhHBFEtR4S7fVp3JMQXYDX6ar/Q8uKL29m8WTbxBfc3/GXC6fkWSehSP1ZMeCaS\n",
744 "HGfkhOFYnqzXIVdGPZCSA28h42lkV0U+CbAlaekW2O16+yaw2wS2Y/Z+u5KrQxYjw8OhtPpMwmxk\n",
745 "zCHYFCmV7XDgDcVTtv+m0marnPovaK6qMrN//FeyG1n95xvceW6QydmLCO43IwMr3wOmso638bW8\n",
746 "OJys5dt4Nnrl2GJRTkwWmIiJuBAFCpejSOMMYbWxi62sz747d+4T3/+UUnw4+8RvRK2MHcctEH8i\n",
747 "VZaK9alNpdtKd8Ne7CxlU+9c6RX4FJaUDiKLe0yG18Y3nyBvD0y5Y1i6E5Vy4RSm1hC8ZSmyqJND\n",
748 "wQ1BBHcE2Z1OBNPYjrHtxMyM1I8qFRtmbp7JuFRtOjHTmJjFLoXzm5tlnCUMJ4LkYSLn0ixjYkFa\n",
749 "GkLQVBBBU0sWDS5C5uCiQ4sQ1rdIkQumla1Sgngh7WAEpTCaAmoRQj/7SOTeS3FFxiJXETvmNibq\n",
750 "mYgCK91EPVWESLRmkmOttxH3OKuVQvdmBRKtTKxhl3bg0g5jh6tDRMkt+Jcm4nhE3BkPxMVhaUF9\n",
751 "K65YAE/yJIO5AMtIL8jnkLUARAsdn22ndohIV8Q5uTJVADOT4kDF26VF0iL742X4Gr+ARunQ1jGN\n",
752 "MotZn0LZiKOIc6HCEV8g9MWgc+jqdKwpUbCrXfkH84+CXV1G3Md8pbRQalfBwYKjwE+8DA72BQ4Z\n",
753 "ChwFdQXsQhXE58+hIJiLPUwzSO0o3lecKhazeeAREDWk6zBcZjtK9pWkwPgugPH1gqzMJUYuB+ci\n",
754 "vAaC8V4OyeUayA0C44GJ/3TDJZj4VzLZJHWp8XrjPYSKUIzMq5BNVoFcBjkLchNkJeSVLSFcHLoU\n",
755 "wpKAAxtBboCsQCjja5BnXmtD8kBY6IGbWoXOJdD9HiUCW4qgTyO6Xphe2wriiMYmHEBdDuaIcP90\n",
756 "eN2Z2CKMvxUE5UdlnvAKZxou4xUowHpVLsTnPgiJhyvQ6FcYSZ5qvgip63shxCiF1oReDsF5hDbf\n",
757 "wetcDH2C11mWa//rrP2mh+ArtA8pwp6pCOdsAXBPB0Ff1rT8a11dX1vepPy2t6/Zsmjh1jXsd+vC\n",
758 "RVvWtAtzip/vDj0501UZfTJUE2uuVrPR1eJt91us9e2elh4dPzT368vY9S/Nm/uNZcGmZS919299\n",
759 "Lhp99vUl2V99fKl79lNNTUvbq03eqLeurayxo8bd2VQxq57kmkpunVAoPM34TYTvl6xAUUNVMmkI\n",
760 "JOaXgdAYH0sCw4J1QBqdnAAZAolZZenCoH7ASa5m5CWyDwBMMITkJpohITVvbt7ezJTtZjLOQ6SP\n",
761 "lPaCg8muz2TE3IufsL0HjH2f4taSredZcTrq7oPtvM0bBzgBwIoUJ9Vb5K+sj8OifxS84gA0gbZA\n",
762 "PACZJnAUNXxScFNEWnvhplAeHjb3wO96GO61I3hcFkblrcpjylOlg3h0mzs+5dGkehzAMyP1vXjm\n",
763 "fjwuEujFc/ZNPkc63Pro+PBYLFqLBm5+2cJDYEgRbxgufzlUNGL9vfLmLq+nq6m8vKnL4+1iMvIr\n",
764 "jnKeL3e0zmitWlRbu6iKbTxyhP99X3eosjLU7cv+DlctqquTzy0rk8+cto9vXzvxmVCW9dPEpdKq\n",
765 "ST9NqXHELPtp2OrZkJaCOT8NXDTS8aDiCyAHzDTXzDSnjeKnyeFGPs5PE9Mfs5y1fGC5ibAa2UUT\n",
766 "079Tf7L+fP3VehXpgD8S9kI2/ZG4F26ZsNhDThrGggWlPk8S7BSnFO+F4SRc3IOfH5XshTMGaDmS\n",
767 "vpLPYuUMJ486zyAUW4+MdiBjJY+6zwCyTA+LRxQkDkyco4ikuw+ix24UBHE/kt4DpHhwaoUrzcQj\n",
768 "Tjv5gchD35x3t7qnewatoeLQBnh0oAFBE4JHh//5f8yjM35r8cMOHf4PmXzin/iOIFLtgyffFtUa\n",
769 "VT3Z9NJZN85tgc/aQsn4SQZB2cw6NcNQ4vJUsoWMrGIa0hb00BZgyAWSQ6g1xEf+7u+62P/5e+1f\n",
770 "jgoz2/9OtuU1T3yH/4Iw8f8ze37h456vlquQEPyOgShb8lG4BhJeIex7HAyYOSgWapFJN9kiSaUj\n",
771 "HBZVYEQr0OhUUdUaEUjsaGux0lb2jwniZDCW2/wu+6+LiKBqH0+1nzjRzs9vPyFjUYT4ffyAkCaZ\n",
772 "KyWVVkJGZYJWVqpaIqcyQYwifMnJoo05SF51BsKKPZPFBiJ5k6ewnyTsvuAMWNZGQQgelyBOTiLx\n",
773 "MwsPdxRj6CBWsTOA5coqY3IxkgO47DQICuAkDxecwhWHccVeKjNYwv+7oLN8g7HMYzZ7yozKb9BS\n",
774 "C1iJWovyK8ya+mf8Tv0r+0VfTVwVlvJ5wjGS5weA/g+7cSZmkg1ZMoo+bO9jGj0TGzVGDeuOfETx\n",
775 "JBHAw4R901DJhpLNJdtL9pQkSk6UpEvGSvRQNcwBG5R4kVgOBp2pJVtaF5xyyvbecqu1HP9OKBvC\n",
776 "66VOZ+mUf0yOXsytEBYKWmpnGbdZ1jygFCWhEwmK7pGE2sH24FtinXoF1kzYzuWiD5se0kCwbSM7\n",
777 "uZ0p4ECUGQLhMPe3V0CJtTsYE7UTkgpTPRwEV4bR4Pkd2oe1qrWK/6OHVZAz4wI//gNFDwlkN863\n",
778 "s/eqn/gL/r5o4xq4MDdH+LZUDr1vDKhB6fIxaNQxiHSbQYZA3GoCOHEHpH7G5xgvT8xJY+aw8Vqd\n",
779 "STSmYXxgU6g8G3w5YlITkIIvnfAFRmrZDuPYIRVFY7Yrpolp+PqEDwzz+pwCBMqjhOLEnKzH7jh3\n",
780 "jrvC3YL6WUBzvgDw9KAmUBSqTcwhvKw6K1PUB63rrZusItMirIeYrJE1Zyf7rKusbBRVUYuryMXH\n",
781 "aG0mubl2e61A1awa2Y0ayO4RxmPD58JXwrfC7LEWYyICppCS3criQGqddqN2KwT3F3I1UrWI3dHA\n",
782 "Xr0flcJSxaPFFyBTixAtyWhAZve7sFifNX1gYm36uemvYPDYSYFekFgoGhuxV9LH0L1+BPI5bKcv\n",
783 "V74GseJl52tYcQhw8TmAKb1WtwNgSheALPQKDhyuO4UDVyHDrGwCE0CbEX6EqU8JRRo0dC+s69Ra\n",
784 "qt5Kgj8xg9+ikQRPdxVEi9ZTCdLLILty9Vr3o6n7qYoPWvkqIuZQ+lQ6yZqRerkOLYO1BC2j5q0F\n",
785 "oaKWK5AM+A5SakYZMU1aOrCsab1ebXGlKPuK3a1ery9SKYYiWAvDXp+YNYKMV3dH3FXhbk+wpm2G\n",
786 "u7DNHK/xxGfWOCPz64M96yvbjbW1PmPQ1Ogr4xdEg2UzXCWmqhl2Pm5wNnY11vc0V4g98wptTmPQ\n",
787 "XcWPf15Q1dTdVNfdXCnO61J11tebXZY8Pr+yyROaW8KvEMzVDQ6Ht8KipzWqW/gK93NaI5slDcf0\n",
788 "6t0cvIVsUMjcS1Q4VkrmYCL4kp7xJTEznR115zjPf1M4Du6/gtFd/PtslvYwJT+JSFxheERUP5A2\n",
789 "w3gVU6Jok0PqDTCijKmnQVooYpSS7S1X8dnV1cVuSesU4nEe8GOcjvPwp6QaB2Y+hJMTIBwTTmCh\n",
790 "RwWhfqTPOGQAf32aoLbZn+QZLg2ycQHwbyrB1Q+yHgbpbSBjICdyZbmcrCVOw8MynJOcZkx4Mstm\n",
791 "Tuk24nM5PT9MMZtm40gh+3Ox2Yk/Fwek7cVyYhyVTqGQ2v1grqug5Mmw3yCEDt8Dsh+Low9bvYBD\n",
792 "IOjF1cD9WWl8wcim0hbjTjjLVmIKbMRkiFiRGGs9DWYRsfUC4Odo+ZlyWBkrTgMtMQoGTcot3EQS\n",
793 "ByzDJVTW9wChjuH5kVxLsDgnw/k9+ew+1nwf+5Hxdz9BQ1ZgCu4g5DWq8WiEmXSFca3xFePrRlW2\n",
794 "LUetZ6ArUZoG+bEAfygdBtGiKRGgN16oulYFtHhZJdSyqSJb4KcFkZn5ZH/c1d5QJojlje3u1kWl\n",
795 "obrnZ7asinlqYsubW5dGK/nCuU/Z68IVYXdHg6PJVdfaqMiG3s5lwUol1+EB5Xmty+bK/oSNJx8+\n",
796 "/rC0HiNgCUgAuzQqOAQBbvBu9gq52ooP3+NpukclXZ4MeDu9rJe2g0+M1aFfb/uzWEXydcdy1z1H\n",
797 "17XRc2L6Q97j3nPeK17WcRtywzEInRwYZuzvbcfbzrVdaUMIedu0PN6pbdlE93RI27M663ByzH/b\n",
798 "jzXeb/QTcoDIhdk1d7Iy3iL+r6XYfDZ79qDUahEyWjZjawgkxghihaEGzTdS1bAYFpFEJDBSSsew\n",
799 "0jQEpD0N/MBIJZtt7fNjlDIGP8wiefvsImUKTcPR7mY73Vgr3c3d8qpM2lA3IWhDP7bzD6RaNaVd\n",
800 "tbuzdlVJi1D5FflrgSsMmOzkioK1kACBAp1cWfwCnKuwyUtnYRhaWfICVB6IkdILYOjrAhsDWwNY\n",
801 "8KC/rW1hh9a0vtz6Wis7tBYpTadms8vOd1xFYsqKjrUIzD0FT9L5yfK0yfNdV7vY8ZcRh3keEeYf\n",
802 "IOZ2Y5yd8UH8ZpydsXLBC6jI/AGSe1cufGEh2gDD4AcLby5EdCBhg+gx50/m8P2AhyydgplrBRYw\n",
803 "WOvlNNIVIGuU9kqj8G6Nok0nFz4aNCc+tK+Vl6VctpFS9p3mVTjC/6XFF612t/ksFl+buzrqszhM\n",
804 "1Y1lZY3VJuX3A6uv3OgKx2tr42GXsdxnbY97Zj/R0PDEbE+8/ZSzFZe2OrO//LqyxiqTqQqX0u+3\n",
805 "dc665rK67qDDEeyuK2uuc+oE43M9jfNby8tb5zf2PGdk43F44gvxFW4Nyadu7qdwa5VAkobcZFXM\n",
806 "9pN28THuNpenCK0AUMjHaflD+RvyN+dvz9+Tn8g/kZ/OH8u/nY/T8o2Ma0FpseE025Btg22zbbtt\n",
807 "jy1hO2FL28Zst204zWZkvFIazNV6KGPjswwsvigNQbwMCZgJc5rE8akSrPp3bIuvKBLs+NuPbimG\n",
808 "9Yf/cTK+1TnxOl/MesaJ+CKmmaqN2bJPfJqTBLjaxwSwAA8TmcXrD2zi9XNdnHIt/xldW04XBqZc\n",
809 "yAvTLuQ/G8/nP6MLBaYjjAoL+Z0UO9MC1VNAFCT0VIEQoXg5bEarhBeSFisDJN6mcnC8uarVw/4J\n",
810 "CyGws39Ce/uO9vbsWi1Ui3mcn5utegKJCeoisT65ybmNSYFsBU34MxLn9FOUKpSS+dxq4Nu8hu23\n",
811 "uXehi3ydEKaK1FQYCba2X4P8HORDEJd8+acweD6NsIgPsFXhojwc4Acn91WkKuSnudPQABAvkwRG\n",
812 "Kbu7Tz6PfNGvMQLfY50s57cwnrYEKWwBkEFIe50gm0A4ZAKOdWLE1AQACuAMTEbZKKJCrj6irxZC\n",
813 "gPQynvIeyB+BVDhrcTSD9fAmGvpWxTEs05yPoikJnsxaipA96T16U/n4dbzfJibrIJQSJqqoHLL3\n",
814 "PM6PIDBnK9Tlb0Pt7hGXQ3TeAZMyme+1YD+ElbEV5CbIUkhlpJQTasZbIK061kejuguAPqMkzR6q\n",
815 "N4stNTKQWkEAW5SM5vXlAUcdjEyPgjbR/D7ICmdy3sczYGo5l6mMkEx8mVI79ZDP78D8eAfhLyhL\n",
816 "kvym7Q0gR6+0s9tttG+FPfQgpPU/gIFyl+Mgwvmp/iZCfJJtFfEK9sCVkOJ3onPeAtkFEecuAqK0\n",
817 "MGT5yJoFkoSY+DxVDgXpqUF9AW8PrJphLP1hiEURfKBaFB5ZhQzSd7GkvjljMt7/TcoAgRqwC+St\n",
818 "JvREc18zLHDNB/HTFo4j0v8AIv13gRwFOQCb+S4KZEBeZQRepTdn7Z/FLnizfX87Voi1GPyvCltg\n",
819 "+CBHC8GSrwShD0c1uI7hSxyjNGF0MWlnyxEAdZWcGkBrfBVgC6/at9izPSnFEQ91Jle7NF422Xe7\n",
820 "siWAWetdBxFgdAC992MQB/rs39CP9dhaANIO8gxIIUgvDIJhyCzUgb205QNyv68Xtuk69OPT6MfT\n",
821 "6Mc+JppIBpB9CPzYj67cj15shcSzn+I90FfRXK/Nz3XdAfRaFOQAkzP4SlE7zcJjsUYaRdmeDAha\n",
822 "KxNDH7ZDDjXGmx28LToUD8smxvCMnhqh1OP1W/+w5kVHwNLuCFrX1I6P2BvmUJA5BZ3PabALP2z8\n",
823 "yrMvzmr4yuImRbQsrxQ80WBdabSmzVZb5DH7za3ucddDpkriseT/JZ2riPvm2/mqAlU99H+q3xfT\n",
824 "K0BLquH/yLqXvFJ8C8KOEwEI64s3Ybs/BwtYxJhO0SNYSvoMWyqne399TKvKeX1L4nFlXfpPgorL\n",
825 "trmc+xv+GrX5/3u7QJXP2pxvlPPTkku4QSzBGjRX86jV67YmDwB2TI10aYKamKZfo/l32j1N96OX\n",
826 "0MkRmdmmT1U8EQW7bErT+YTS9i8fZGuTMtIrcpydO/E2r1ap6pNAwEImKNzVHEDbTmSD1WDbJFc8\n",
827 "2CAHwDa56CxFsWD9VGdAtXJZ8HSikH2w/sKhwg2FmwtVdAdbWupEaGGwbBpYneICoELOhoci8FHE\n",
828 "mUdgbxqpvVpC5C+RGXlcQd/npOV6VGDK2pxlS5k26zwzh/jq9V3PPru8t7CiMD/fUVBWXaJZz+8c\n",
829 "f4Hf2b55YIlKbBdVJVUz7K/Cn47++CXrD3xLP58HDKrb4BQcCjoUZlAAcVgpdw8Mv4dGn459TCMn\n",
830 "x4tidGqGASdepH4ApxfMY8WPxNxUZpInKtPwIQXhgK+ltd6F8iXkykYZJipyJCXqp8ldSq/Vsp1a\n",
831 "pddK2E4Jeq0M4yF1Tg+wNHEgltepX6If1K/Xb9KrEbABkbAgjYcVgo4UY4WkfSvkOKDdwI8St69E\n",
832 "wITUaweW7RTBjU0J7e/s7l9WlpRU4l9RV9eeR7te2GIuKzOzf18+y7/f/rjPQHGJn/E3GR/w8F+X\n",
833 "DCViPRpck2YyxAjPpI6arIiCmoTSEIJmgYQHTDyghVEFM4NxpIx+shXEEzmplbJK86dOIHSYx0gA\n",
834 "z2pPEUW6BCRBTYWEPoKMYCKxSqkgDtkHpkhknLNL3HQiaw3G5HksOstz1nsqBnkY5B3Y4gFmwT70\n",
835 "KIHgYFFCSZjkaP6FXA2YNSCjBMUFQeBrMMWdx6L/CQiViZ8JcgDLvB6r1UEsSVGs6fNBrhOQ7ztw\n",
836 "hi/XrkGKM61+W3G3V1Ft4qL5Ezgy1VkgjAFpL26lwa3ewq1QA4av0mZBaB6BKafAOFMV/8vxf1RZ\n",
837 "g7bmJ2dV1cRWhOa+WNFbGg9Uz6y3OxpjXu+Cai2/TvjOeb2uevZTTaFls6tjHc66JnvdzCpPR4PN\n",
838 "XMKvJ96J+fa3ImZeBfceqiPfRt9wOsIGlYJUml5NBZLV7EeVAVqsPiPX7wQtYSfBzgrPgEAge+Vp\n",
839 "aQNMlNtAEiDAoJbSTuX7E2cpnPr9H5s4lgt259OKG1JHhu88CryzZHmQgjvCJXsLVjA1uwrR8L9z\n",
840 "avzt42fEZ+M/+x3zgJt4SdAIaa6O/w4bfkifyAIl2DLSEL4ex74jOAvTXGppjJLnqdRky+4wdcyM\n",
841 "OgS0zzioMyON5TrFT9dwCT/yJ+itK9hbV2By+GW2qyXrHJg3Yw9+Yg8VxhE3vXwqwvfyK3hxCoht\n",
842 "8hXhdXherYJPEIZTO40HjEeM4oBky+U/67F1D5YHXbENweorEVt3D4KWDkJqraPNgRojbDt1pOx0\n",
843 "2aUydvlBAmcBISCotSBvgkRQGGqFB+Ch3hVeYZhL7TDuM6bwSAsedBeP1LKtpKbYgqdR3SSKNtQr\n",
844 "0YaqYekd3HoU5BrIfpCLBAyEh6wDAfgW7xbhms1Nh4iJfeQIEvCUb6zVhvj9r8xVl7ojtZb6Ylde\n",
845 "eYG10pQndr74SpmmtKbF21JfXVBRZHeVGkTLi/xXx/eUhWeU5RUENRpTpdfEPxne7myb4agI6vS2\n",
846 "mlrjt2mOeBnREI5cIfc/UVViCfhcfkbajZm9HqQTJXsxOBi/E5HYNKJV0ZpJ6ieOMm5fEJDEAiXQ\n",
847 "6vF1ebWFMlBpIAuHIPmziJIDKF+MW8txo6KCXnAeX/4aSA8Sk1ZQJVHYYslW0wZih92pr2BVgTDM\n",
848 "OnCWQL7WqlY+xK8UPrsTX7MmPv6/+cpnhG+N/2HXgQNP8mcRq7hqYoxfInzM3llPpZpFxl3dvJXf\n",
849 "z78bGu8QPnZ+WZa1cRsFKz/Gmbh2ISK1eFHVzyujIcGyvaSFbbcYR8rl6AQ2e5vT7G+J9nSinSm4\n",
850 "UFivwE7UCXIcBGAs3CRgnMINyC5neMiHRTtRthPVyTUuwSTq5ViF0igCzpInS88j6i4FR8rHyPDf\n",
851 "XrqHHUhEjSNWdlZFVb2i2ib/quIX0Go/BRMO1sM5lkoG3wu+HxQppgEhaOzPrRT1BELK6n5Eoe3U\n",
852 "HgCj34klZmf+AcQ17Cw4AJtfK4b7PpBekDcx7xDmJWTju17DqkIwAmuxFceiEMdS0EaaDxShI1D+\n",
853 "zoCchmYC6DUpDqUkCpJCsvaK8FqocKewfT5yNcKefzhyiv2kzrRfbr/RLiKMRkbwf1PcD0WbdLMd\n",
854 "VBoZwzdO7myQH4N8A215H+R5kKsgrWgkmpsEwApeDS3sATmNxh0DSaFxp0BWQBO6BE3oDMgxkKNQ\n",
855 "hy7B7HoG5AbIsfbJEAyfUlUou9hNQ6WkQIzWXOH7V8sCnZ6aOc1lvK2xy+/pDJTlVwxEm3vqTYLr\n",
856 "mVBoVZe3pnNFizkQaCwVukyR31/S84cNtz1zmiocAXY6+61omjP+A1+gonmud2mwtqZzZSi0ssuj\n",
857 "K3WXLR4PepfHg41Bjmo1fCZUsPWxhb8olcKodUiWxgmPEbGc0olsQGd+Gu71Usac2bj3cjAKJ7wB\n",
858 "qdBbStZmQKdXyEcrAih0PwP1G1o3I/ZoSVgZ8xQ4XviQY2laCWHJp7XLIIgjXjaAi3yE5WWXwXe0\n",
859 "lLaK0bpOtRGqwavwl6wDATZ48k3DfpTEewmLJvlDoiDkl+yGsiOnMUlhmD96cobdHghB78PoQZYP\n",
860 "DdT3s9haicoA66o2It8DqRTJldUvVCvBWN8EOQuyEjUI5oNshAp9LYh6VU3Xmu4AJdUCzNQLzdea\n",
861 "7zSjelWzpZmtIsm1qlfQ/OfR8lcoPQu6xsYCpcko7SWX8R1G4UTWfII0RKNGs0lRA8lk9XtozUto\n",
862 "wxqqrIf4sO66ZXVCtilvMBJyF+esz5Qzmx1hrRY5FcHrbpXL4pEMsaPL3PREe21PqPIbM+bUlVZ3\n",
863 "rmgtrCzMt+X3D744UBn2WeOh2nBVoeCa8USHx9bQVfdSnaCqifb6Wld0VInqqCg8s/Tppe0FFYHq\n",
864 "9q7KxjYH47V3hBbuHVpfngOiCjDZHwd6LGZieZOIpOoBqUjkh2MFQTEm9otD4gZxs6hhmoZLVI6o\n",
865 "hxOCkkbJZ+REccbKxJDVbXj6uVnCe9tlHXQxVycsZG3QcN+eNJ6qRQD6xIr+i/pP1T9X/5X6F+oP\n",
866 "1Z+qtewBZrVH3aruVi9Tq4elz9Q5QH4ByQ2yBVdWV7MlalQZaQIqq5oXJhOqZINs8hR3EeEcp8VL\n",
867 "jCuZ1GZ1q8ezmEyz/2P8KaHlN42/aT9zButMC+fk9/J/w6m5PH7R2xqVXlX/NqcSmb5MCv5Acok4\n",
868 "mC2IkA1WhtyoZ9JihuCcmeZKyO2cpDOgZh2shLfA/4AuD0FWSKeMBpchaBCHUycMacMYyh4YUO0e\n",
869 "kpZc4ZwN1+XQyO9T0rGcI9yHLGEDHaVMMjkRvA9Z3AYsxvcpWt+u8quiqj4VjiI74r6ajqr96qi6\n",
870 "T42jajYN/Jqopg+h9Mvhd7lPle3tWr82qu3T4hw6SqXs7Tq/Lqrr0+EoXuU+gWnZDX5D1NBnwFHA\n",
871 "EK4EhDUwc9if8vx5sIDiTwTT/jQcu0+zTY9V64tY1UT55q8Hvv/9wPhF+rmdqPrlL6sSRPENZrNv\n",
872 "8JfZb9D6tl6lYd9AVHGqemkIdok9RLAoDskV66FBwIwBaCYq3uYEHLwTFtnjcHHrKcDtNgLc8tIc\n",
873 "exGxPnVCl9aN6cSBlFHn0gV14rD8bWT8foK0BiJ77sNIdyhfV8NbeC8f5nt4NiRXKmUdpqXU36Hv\n",
874 "oFFZVF5VGN/hjpquVFvUXjUSQdmVMCuzQ1qL1qsNa3u0uBn6/A71OYqme3Vh9Pkd6m6NwWLwGsLo\n",
875 "7jt5dGWeJc+bF87ryUOdytVoxzLqZtxkGetrBI5qfR6iCepj3v+YrgZ2Mefk7lBf/+XbaqXeU3Ym\n",
876 "AWl8UIuxzIsYy3gO5YrsRnaDzB7QgyJYgUiQcPcpvcTOyeMYg4DLjuOUPIxFZRAjkt4u+sWoiEO5\n",
877 "AgGPHcYpefgy8UIuq7KaHYtgHGnv4KW+HqOXkmM52Njh6H0OvS1QvZiJbC2ULOwV+55ylor8ZiKP\n",
878 "wUDcD6/Cu/gg2rgbw6sTrbolylEKd+jNLExID3M9eDPCYFfTGMDryQODXarGVXfwehbRK4bxemq8\n",
879 "mTww5GHRw96MTQ3cAZUupOXsBAB9+SLd9EL8HvmNeC7OXuqy8Bln445I+TbIBUwZhK0MQFxsvG6S\n",
880 "gdwAzyWloeAjAUaacEwD5SicKv4rwi0lkmGhF3RWSA4k3JOY/y7I25hbBdC9YTRCDyzHhDpFxecw\n",
881 "SbYU4X02GrcadxkPGlVM9DusPwXEf/xB2gjwrF1FB4sYu82Cl1jMTFvOLm9md7xLyKuuC1hXL+8K\n",
882 "96kbQ7VdTDv+kcllLRhcOX6RFxc/pauJx24jtjAptPDttG5puZ8CGWCTUqExCex9xo2FTHJMuC0D\n",
883 "budAtqcib/8/ALfl9PaUXCeErsrWDWFXqTJydOyjNT/YcqfCckcORQ1b9DROakhaxutWs39HZj33\n",
884 "9Pjbs54HcPf27exberlzvI/8kW74I3nCQlRnsl7MTsysTnT9FLekb3yC589la6OxscAdEI6QzXIX\n",
885 "U+ySscL+QuHfMVMWTzVT4u86xVQpbUaK+VDxBohiu5VaOlKsGEKiPjBpNlFGjFJTJwljo5At7UBV\n",
886 "HdZn2SwFRD1kPzwwxUo4zSRIMRuz2Dt9QTEbL7CRruHmUMTGblRWQwqlINdwSMbU/Wq51sPExMRH\n",
887 "7MyCKdc8za4pTR5SHcfp/SqsOrfVcpzJxFV2Rh7FmcjnPsfObYkV7Vbh9HOqK6pbqgmVdiBZpHKq\n",
888 "hGH2B8shy3HLOcsVyy3LhAV/sDgteDK71x127TtTnruJ7ZekOK1R69KKrI3afm22HoUw8U8Txuy3\n",
889 "cnJ/kbCwb2Xpt0z9VnmT30U9/Lgvl7DQJJc2u/CVqjZA+N0NmTOGvPaxKszw7FealhNKlh2mp9KX\n",
890 "UT7V+mzNvuxXgm3HKAvwPWXLy4QBLhUvW1n2Qpk4MO3zKbWai7P6kC/3Mf+XqDPpbBWFqi7BGmkp\n",
891 "t+W+7IMUL6hKKqqLBe+X5wxNzV4D8WXwsY8YHzPwf87YUPKQ7rhOGBjRqqmuH1u/RbDBFkyBHhCC\n",
892 "FLDRwgbyR9h9F+RrWOeZ2FjCZJ6UWwgJcwXGYJdBAgpj7swD+SlqygHpcruACZ0QTghpYQxJ9zoS\n",
893 "294C/8cikPxAfRMRd3+MA7+vppov0tcgRH5BGaWiyqRyq0KqucgoHSIg1IdLv0gih+D4JArYCXJi\n",
894 "anKt+Aq2qXLyXqwkP8RRVPlRshLJE66wZeLRyudTKuY9VNaHh2E6eZH7BCEAq7FwWECACM36joIB\n",
895 "1uJJlBi7EYRKRB/Bg7O6OJV0NoNo5Auu51ArCa3BA6mpVINiIaZISKt2+xAx/8Y/PHuDF9b8tquL\n",
896 "5//+wvidO+wjKjGNhC8SZ+2XtiFJF1VVBLLjUkxjEmWXhN8V1fiw8pmLapTvP6krfItgZMArJZ7K\n",
897 "3MT0dfxMfj6/GhLxv+HBwNHB5P0u/0P+Z3ySf49/n/8Y2oxAPipoC2oV0xaoElwO/5KfUkhOQYli\n",
898 "qoKsIyRPaS4yhs6r1WZPq0dYOP4U0xQEfpy/d+ZMO1MX5DZ+h+JE1FwDJvWUYBBFNdBmuCynl8vV\n",
899 "3SZhwgOzWJWwsH28gx//zgft2dpb3E326nnceXavJByEcoxoLlkii1lDKRrSZlhTYrC67YauOoaU\n",
900 "gaGCDQUYX3xASZeYNsqUOnWxoun1b5iqpYfUg2OsQ1EAK4mKWEjAPa47p7uiu6Wb0KkHUkU6lMti\n",
901 "assm3TbdbiY7ZwvSsMFJGfi8XBRXowXucLY8VK4wlCli1rLlX9saYR/5iSe62P/5s0v7nhr/z/zs\n",
902 "p/qe5NezPpjLcaLAj3Ez+PcTMwLS8Rn8wEi9msybMxByRFUBpW0gt0FcjBGOuFDJlyK/LewEKObb\n",
903 "QG6DuCzsBDMbjojJkzYgsa+zkfXZOWwNgmwDKcKxTmy5sDXWqAxUPesyvTIxi9lOsWFqZyo7SsUJ\n",
904 "Sa2XbYHq8xjwaojk/wTOUlhM1j91IZsU7xd+XIjg9DQqNRcbRxzCA8aTRzyyjEXpHCl83Esw5MRz\n",
905 "iJKXc4iScdglKL6BylceRFTDLvtBRDXEYcq+BBIFiSPEVFc+WT38OkyOB5HXtKvmYA0iWWohA49O\n",
906 "ZlRK5/HYHghvF4quAfmUguDDeGYvyBt45k7ImK1ZuNAB6QLIVTzsAuGqg2iB1XINz/svCJXYWcMP\n",
907 "mFq8qGcqO5yyYAxTJcIpsqEo9Aq2ZXWm+lp3fumKAJMRm+d5mp2F7EdT3+jp4l90tDh6/XU6s7ey\n",
908 "oYUExuLehRXB2VX3sZGVHGFf/hdhJTch/FfGp4yEy5Itr0KCCpuEE+P/yhcKK8OyfYIvZvN5EbKt\n",
909 "p8tnFCwGDZN9Ipq5xAmK27GuTZTz/8hkmXLuH6R8DvI5R7khAK7KCed55BCWLpbIDnZHWkqjZxIg\n",
910 "VBZpe+U0ed0w1VGumTr+lB3yDOtkr7la9tvkpaUSG029DAYHcHQkh40Y/bdhPf2vIH/moKrTjr9y\n",
911 "/MLxoeNTB1WlTh7VndFRFWX7Eftp+yX7dbsahcHesh+zn7V/YL/JdpkQn4W3hG3UYs1mr/kgyEfi\n",
912 "lS1eSxc+Gon03f4u/v3xL5cvsDXOrb89/ieOkGNhictWWPG5bAf6Lve8YOHvM+1eQ3UG5fJgV3Jl\n",
913 "hQkWpx8LlVxXULok17cCE2Ta22QJP0MmoUtTSTxpiGwuiN5PQqQShlOIDXFxTC7LwjxzsNGgwt3E\n",
914 "lOp1Mk9FATsNlw2rnQmB42mQXkgVVMQyDgVuFqnYIGQ2uQurTi+MIndhLlhO1o4VWI/bFCuNtBB3\n",
915 "mIeLI7huFVbYz3Bdt2JMkeYzXYqfgvHML/pJ/e7d9T/ZXbd7dx2/enfdnt3Y372njvpuLvRBxiMr\n",
916 "uNtSAbCxDtkpBX7ERksFlQ5ECk0h9EEl218u1rvd+Vi+RgvwwyNOUunhSExeUF2DUH0SnZCESaAQ\n",
917 "xi4lMOM0mFs3lMGUQVELT2GrGwYh9IjkA9mZNQGzLWgYG0HeAHkL5LQZn+4U7jWKi7fgbArgJ9f4\n",
918 "LpBRdo7JYjE/RpFkW77XBf5hbZKtJO+bPKZHFEr+q6aZjmzeBOvLBxT7PYP/O8lXwXpzM8LcYiB7\n",
919 "EPzok71LnWyiQmRG0LfPmKjLSPY6trKUig+kg6V0GhAJBhG8sZuRkRliNiOKKnrkP7RMJKrZnGUL\n",
920 "pa2+mny1TBq2HbcxabiIHTTbcDCJYu3CZNkgCnZbgbVhBUYPBUmvKFB6cSWm+laQI3AUIIIgqbVY\n",
921 "mboh3QOnvo+ZfwZM+gzGwWkoFDdc9xHWdj8XFHgBfpWT8IBeALkKH9AoyH4Qqkl2EtV49vlTfnbh\n",
922 "NThfLoKcnsErlX9WaZV2vYZ2LSfPEzEjeHYc8Oxcxrp8H8QO8z5hlFEjLzumtXQULT2PuMU7IARD\n",
923 "9gntosWfocUX0eJRNPYayAEUJzvgP+IXHsl61PoeSp8o1WhFN5+01s10u2fWWZXfuFActTUumVlV\n",
924 "3bG0uXlpR7XbcXwZ/3l1W63VWttWXd3mt1j8bX8u5OdXzewPNvXPdLlm9jfNWlk/fga6LM1NwsXd\n",
925 "mcXFRf6BFdAbWfyN/llgEsFmpXaYwLkZ0ZNtw8l/F/HAKKmd7HcOISvsNrY5p9GJoO0MLRWI2s3P\n",
926 "SBuwshSwQ+hsrrKAUM4J1+cWem83wH2M7DTMIr7MCCYqGKlKy0Z8qBdAxALA2kkqZ372aia1avMp\n",
927 "MFcn/1CZcuTDMZETCT158uFC+cIiumHCCHglaYJ9cAQjOTJkfJJKih00uDOIJygNSGbalyyOYvzY\n",
928 "5Z9yuWUV1P7H5BAqQE4SR08EeGonJHe5AYlCtlsoA6LdzpYpqGCbFWTkw56WRGcdZRHnUZahkbZL\n",
929 "6LiZzrFQWXl7GlHxZbDehCJuLdz9+BfS0j+zm/658Zf//T3L955e84eWF1+qmF3xPfZv9bOWwbWV\n",
930 "syu/VzmbL/npP7b/tP199h/7uXDhQi4/S6gi37WPf13OI3bJecTEXVzZmogGbMPXugSE0BYGQTpB\n",
931 "xkA4v+K/oxRjw0Muu4RbFgbsOUAFGb1YioN9RKEKTgcwjmh7H8UxDhf0FEzCGcs4xsm2kjjwnGQQ\n",
932 "YxkjYTiZsowCpS/nrEumrKPIb7qDQDoNJTyVnQFCEjAHJT3Ca+X8KxlpUA/JNFrRV8FuFXX2OZGe\n",
933 "5TpDXAkTnSkl7EDVmSqFTemr8AjPqAePwIzXIB4k5R1FpPIdxNhqkJ8U9vX44NprE+OTpeSTkYJe\n",
934 "+MnDCuLJw8kijyRGX1bCXJWw1ziy75UQWWTjP5yC70MErBIJy36VnCShimxGf5bNsRphY8IkDYJb\n",
935 "7a49VAuTlZ8fnpJPNe38p+l8F50vLanlh1Mn6tP1Y/XigGSsJ0tX/dT8J3btsdy1z9G1FukQrnUh\n",
936 "5vgQ8npcM3k59wl1AP+A6gBWcgvFvdKCWcDpQL2aACrXUCGbBCOJBbIbOm/WAky7vIB0Ow81H1QU\n",
937 "azHLOGJmWwvYGphGyS+2OjblEZ84jRjmuXkI2E/GFvUDAOjKYkUGibFBG1NGcA/b6VF2wmwnrAi6\n",
938 "jWynETs9MnSIs6cxW9EBzFFiXHOYSnzGyKCFMoVQqBpJoZLq5JPrAtIhpKA1hZGElbzSdKuJNWVx\n",
939 "EzwJ1MRYGM1divyluXPZEErPHZs7ZfWVC9phDq3BAncKxAcRcA3442mwYAqAIXyxA1Cg+kDOgBwD\n",
940 "oUo3vfBu78PU2A8dqg9z4ihIH3AsD5YfxcT4BSbGAegFbcgFPFpxBqEiJ3Oe5RQ8y5HqXvib12AR\n",
941 "7IU2t7F2ay2CMGov196oZSNjJ5gFFXk6C/IhyK/RA/8AMgo5ZS8izVMgd0FsAbjxQM4gsUrbhoAQ\n",
942 "gAreo4KCR6Kno5ei16P3ouqB5JHZp2cDwQfJV/rZ7MTTiKc5CnIfRI9om/tICrkDtP6VqNNwMf5J\n",
943 "PFcgEEpuEv5GNuOPFJzGvDyYrWE+TF2XOlh4tPBMoZiF8jkAEkf3HQDZiz7sAdmLjiR1cz/IKZCT\n",
944 "6DwkUlJfSRGQk0pPST/CtDtfexXTjqSbH6JvroKM5iSaS+ilX9Tjq8w4iuoGX1ChC2Cd3Ef9QXvA\n",
945 "H2Cy1Sp01yl0132qWRBB76HP7Oi9Y9j6AsSA3XsoOniUkdTZ6AfRm1H2bnfQgZrZ4GEdo8iuu4Pe\n",
946 "06D37uZ6bzmKG0S6ETMRvxafItpoH2ZgD5cdnAouMllrUKxVag3GLXUdtTWzZ9hsM2bX1HbUWeLT\n",
947 "6g1Gf6+8tKmlxRJe0VFdE1vRHH2xquqpzulVBms880KVCgesDM0tnVZoMFxRa89X+GFTWygsVxjk\n",
948 "ucoJH/crTsNZuVlvF6t1qvpYGaL2vMVAZ1levKb45eLXimUEq9HiAva9iq8Ww7AlBhDaZhULSFOb\n",
949 "khIbCWWrL4QjvyoO2ktc9iKjw1UU9NRWlhaWGd4pNuVbnSazz+3M90QqzGV5eY/ltZuIXxopADvF\n",
950 "1RvrXfWiUl8aFv9nCFPv/4e98xBB5vEADVeR9q3KSAHoeeeYkpSSEfNEUvbVaW4yzDR/qsWXfG8a\n",
951 "2VhGPxT8xlNJuOT74sciqky9qdqvOqw6pVKxyQMsYdLCku+rPmZqWVKlKlWxgfg5Du1Q7YOmNqqi\n",
952 "0t2AtOSfiW9qSMaEP9gQ/iFhyPkmxsQy4WPG7T2cX/gEUUNOF2P5Vpg3gE+b3GNNsAUc0erZ0Ak4\n",
953 "zYrSiSKgwmK7Qg5lZ9JSgJTKhMuYcGdiBYNuGYJ5t/uQWzOQvOWecAv0x5q0VKTkDyMgz5eRzkG9\n",
954 "upVTtIagaNVm8Ed/RtpU/9jw7VyIUlYMThVVOisDleIwfKAISJWWo/2jwgWUDNDDF98jLBdUwwpE\n",
955 "0MfCZ4JsBCjJIFYDK1iKyzPmufLEYamwhJMFSlQRcmakGIJmKXK2ykNLWTX9MH0OJxAIhoyYmfDT\n",
956 "J7uBxaEPFosD0JR3gXwKYkPaGCG/DUu1sG18Con8KtQ0NSq79GBrBchdEKr8c818x4yX0JgtZq85\n",
957 "bFYNSyuoNhDkLC0UpjYIO69SgVSQdci13uU96MUa4L3sveFl3GUVen0+SBt6eQvIEZB1AKna5Tvo\n",
958 "w9m+y74bgMldhRyv5WCIr9XCrZuqHa29UHutVjWAo8NSL/70Sk4dvAc2qqu11bLX6vYj1T3lH/Vf\n",
959 "8F/z4wJkWvf6VyDT+hX/637w/ecxdK+il3rRS/up/DzIVaj9UVhDHCDzQerQUVcReXW19HNEVU72\n",
960 "khadRslxFjOyn81rESJIMfNaqJc+kKu5EDL0VlVVayQ8CfU6Ge+u1YY88kwReSsvlo1/+PNSb6G5\n",
961 "vKAqoGszLAqXN3utRkd18Xc++vJw+5MVL4WfpJjU6M9KAxX5lmJ9lVXf1FJYVldmq6txGV/6lP/q\n",
962 "XO+qL8NKzKqKi7H5JlBsayFn5uz8Fyg9rkVYUJERBsVsgAlT55YgknZJvuzagh8iheLPAYGNbznQ\n",
963 "V2t8TJAv4owIbZbQkqRDRih9wFBJ3jJNmNgQKhg0rTdtMm0z7TYdMmnoj6VpaT16ZjNIP+seQKFY\n",
964 "2aTEenprOn4bU94sBGmzKZfHQ2APyqQkMxImZSF7g0L2BgEQrlCPGTMXippWX5gFlc6GlKTgZw2o\n",
965 "2HtNDzGW0TglF4zNMZBiM2VllNAPqv+Zs6XiYfdj2pqd5l0bKrm8atkCNeQI3mgdDuyyHLRgcFtQ\n",
966 "xRyDm+YMXutVkCMg65BWuct60IoTrZetN6w4EWmCyyFUvGajWWAbtV2wXbNhUOfSKF6xKSLcPZje\n",
967 "dTYbkqVfQyZmyj4KM/w12DOWI7oW+TTSRSTVuLXZgGh3qymknhx2whvCljeAp3/i7b5xz5Rhxn/1\n",
968 "cvgrX+ngC7Y8NK54LsxXcf8knGVr0atw9mQRPuVVKAl/tjDZz2wMZAFc4fLWZJekFAKRlqsZ5+vM\n",
969 "VYKcXKAyKA3H+B+IQHZRyQUWK9I2rVIm+Q3+iRrMV1ETSdd18gd4j5DmCrgm7n2p1iTWJzEI4btG\n",
970 "Ro0pFzYnpWvlLCgHY8YOOdbElC0sB4CkhrS0CSiLh0KPwGqx4WZzF8q2M9balBzbICKuIaHLpOC8\n",
971 "Wq+TgULL2V/L+8uHqBicfI0zgPNkrIbGQgTKJj9ovAlgcMA/Qmu+WPkJ0rR2IJMoeb3yHnY+gA0H\n",
972 "qQgmkrlkU7h2sq5zy1TmQtXuUeHpYkFdbYXH4nAa1c+UeitKSmrnNltiZTNKXI7ZLk9TRZ4ohEW+\n",
973 "sJlNdX1pSWlJscNZ8LrB7DRbPY5CXdRY6LEbTWWu/K3FVQU1pZZs//4+698izs2NSUZgvfTDsHoC\n",
974 "60p/lgMoHs7dsMSsl0FfAAg9AX3lEFTnTbksKcJykcHKUoiyGALsqpMAqvJYX+YN5q3Po9iu5AHh\n",
975 "CIwJZwh7LOdhHoU1nYBb3sllQ1HU9yjs+e/AoLsPBKbd5NGCM5D2oSNlyx8ezd2NfNAH6XK6qFBB\n",
976 "L1MKaz2ionuLyryWhra2Bou3rKjdVj+rxj2r/v+y9ybgbVVn/vA9V6styZKszZYX2ZYsyUss2Yol\n",
977 "WzKxvMXOQhYSHCclk/wLZGEZyAwkAdqGYUqWzrSkLc3CAGHakm06g3yjOEthyMyQhbRT3CkJCbhN\n",
978 "uiQkYWhoSymlwf6f33uvZDsLMDPf9z3P9zxTmp+vjq7OOfe9Z3vPed/fW8D/en38r5hw+Iotieqq\n",
979 "uKXIZy9rBFdZ4xjOMpUQHPmVWMXeE4r4eiisekxSWVU1KasyuqJdLoJdfCuHpDnsTrpnuRe773c/\n",
980 "6t7o1i3EVtt/QHs7y2HguaJU0aEi1UKZyEoSirClJkeGeBOgRVcyGLFflv6W4XkDl8E6LEBihm7D\n",
981 "PAP4rEEwsxJwwgCLYsMruCfPRJtmr0OH/Dmg0G0iBv7CUU/mJgwxxfKND0MBegZAeuRBwIZi8OzL\n",
982 "1uKV8m3kUbO9EtxglWexm+KXa/ak/7vYSlmJNcXjWFNI/n/lCekf+3/uJ5PX/jqeSZhuln4KFo5f\n",
983 "AyhI9hYK1gVX5TWARYCzAKEhs2fl5C3NmVHys54oghOeKNJpiOnCqKz0TjrpbzL0GPoMywx8BL4A\n",
984 "6ayHdAYMR7h0ZEN4KY/ulM5BPD8hGckZzoNcKDKiTCCKqcw9mHKHYFcD0nO9pb9KvCIVlxJdwlNQ\n",
985 "wlcXry8e5SCvpG/S36p8HjL6JYQ2CPBX0fbnWkjoDf/bEBkFq9+OhL3+w0igEPZhOYOfht8Fm/JW\n",
986 "SGhnWB5iGoUu8DpQVO8BjIZHsyRIH6AfTNZidaNdquU/jOG6z74M7KT77cewIKIwgB9g+omVdZfB\n",
987 "3aJsBzbOTsAcfVP5duyZEa/RFuj6u6DKKjEbt0CV3QXH/dO1F3lCemK4M4ywY10Q+wcZyoQ0Qs/w\n",
988 "2ykA0TFAD86u/oirZlz1YP+jGQCXl/Q8+1LU6yjWaORmgrlRairLOtCnN9fsAC3qZJQfIzd3wAVA\n",
989 "F7hDYxxYhpFFoUDN+rC7dApBritjkTQxwN4u8mBLLjyztKOsvbgU23KhWWXtZRsndGLfrqLU2VSB\n",
990 "jbsK9lXPnHpyTy/o9HSWzQnjuqiw0zM3AOW1s64i346LtnF7cN/L6oU/Jr2wSGqFmr+Iw4AlVhYL\n",
991 "x1TYy28Z3cvvGT4rJmift441fXp8u1Y8NsW3G2VQLaNIdxNC17opjuMx/+T4diewEjoP2Av4VwAF\n",
992 "tTsIqJWD3R2vfbNW/G+FuJOJTcG0nIly14QNmilXR7mTw9tJkz3Y4aAYd8QtIe3H9sp+6HkU606K\n",
993 "0clVJvHa0HeOa0LfWf8Hoe+Y9Rqi1OFvZOIOPSYyruObhT+DY/AsdMmNZOE/lH6CbYO3/ExS+YkL\n",
994 "sV8tUyIa+JeGbWTZpfCmZl3uiGsG1pbgRdPmkbmRlq+eNOQ3apWJhyIRkbV/ob3u5pjn4bve/ZLK\n",
995 "eOV9dhAV/jzitkRHFgtXxLOCVbiA8w64pafDeUmYkOQOkY26bLLeiivYreMQuFlgZOSpkR0FDUPE\n",
996 "oWoNpQy0aj4HW3bzSraWbWLbmRzCSqe4HDxPihpgE/GlcCVaJAruFaDg5t9jCQGHrvSA/giaxmR9\n",
997 "L5Tb53PAEZizNmcT3NBzBnKO5JzMOZ+j5jfk9ObwG87T/G981Qh1cBW2T7qR33msErqh8L2OJziX\n",
998 "mw0eD1dL8DJdKauvsFrLwp7GjqlTesR/jiy+/a5Jk5Yt/rOJwT+78PADlz5P707P5fQjktN/ZORE\n",
999 "h0PSWcCjeXLc4ykY5MICxQ4h6QhQQaQpXILEEztE7knwEuCi4gKDS8YGtpXtYqqF6VfZaTSB+RDT\n",
1000 "aJQnihc9H8vj3coR6AppK4Q0H6rsbrLofyhnQ87WnF1cGgOv5pzOuZijIj4Dng2e/iIkM2A8At/w\n",
1001 "XhDGDFiOWCClt5H/BX6La5IK+ivcUXF0qR8nkS9dRyAawT/yc1WR+Eu+ynEJNUKrMEdsk7nNCipA\n",
1002 "5Y1QpzMBjwKSGKzvB7Cp5D+sWPRJScD9TBYeSIikXkgQc4US1uhRPHQKMAhYLNJ5XLpAFQRf/lS0\n",
1003 "m17AWhWZrUMPBK9EqsKCZfwIvRyZWS1Vy79CPKKpYOuURuDYNwuBWM/cmlmrzuQda2ZG+yQ7Vzom\n",
1004 "oPjQM+G+gRgKJbTJdH9mfymVM0REhEi38WyhhfB763lqvXzZxRVc7LLO7EL8An5LQrb4P4LnPa/M\n",
1005 "iHyKE5bC9nIzEt4AyL4OOYLs7aBeIT1E7YF8dg4wtJaLiAuHmFjpPnEZ1s50+LqVXEZGQ8zLJqJH\n",
1006 "AOdpPMxy3MBJgpegkv0k1CvS67Vb+IogvdawiY836XWWzeA9XGfdjCO6Dc6tTnwX2RTBn4mbJuK7\n",
1007 "5s3N+BTfFMctk7ZOAtX5Bu1WZLPBsPXabNY6NyGbr9Q9hZhDa5s30e8nbeI/dAWYy/Zp52af8v3p\n",
1008 "iVy77bR5qgsKqj22zN+WIjkGXFHm73DoU2/xFIlvF338VmG1x2r1VBdm/lYmQ0VFIdxCf9n8T7mB\n",
1009 "jx3ERUOca4v+65FIpMuwvbzPtAanpSnTIfxJmmaZxLHGrjLjzHi6mX+5mv+MxrFbmVr4F3Y/r0vP\n",
1010 "aF2SOZny1aOlp89oL+MtnjFdRpnjaiDNInMoGFeNN8jPFsrimVJ1QiEfK16jsQJaZUjoEGYKt4t7\n",
1011 "pFkLePnhOAfSM7fh8JAtiCsDBLkDnUGTNzMMn0PpoNCERe08SG+tkI18Njo6PCqPDtK0zIggPQG1\n",
1012 "tRVwH2CjosAqo8SAoLaoy9Rcd4cSC02M/0JRZ68JyhhGYFbpPR9+5rP4ynw8LU7GOiOgOzRXe6pD\n",
1013 "1TyrjbN4BrMsqU5+cydu7rR0lnXymxdYUlP5zVNx81TP1NBUlHsnyr0zMwAt4i9zUWYAauQfGkcH\n",
1014 "oEWZAajRkmodkja2wjCIlxFAGQFLoCyAyJGD+HoCL2YCipngmRCawJNNlOwYTLVaEIyJZ9XNf9mN\n",
1015 "X3Zbusu6+S087VY+4fOxMHUz//nN+PnNnptDN8uOV0sg9PEj1lVDlZSDoXs1Xtjy6w5UU/BCKYIf\n",
1016 "TunSiMMrXme0moK57pOHLENmyJqi0qwY2K09qD3OG+zA8/q9+sPwuXveuNd42MgvducdzDuehwv/\n",
1017 "Qf9xP74K7g0eDuKidm/t4Vp8VXew7ngdLiYfnHx8Mr7q2dtzuAcX0/dOPzwdX804OOP4DBWNUMSc\n",
1018 "mjkOumr00XzCd5/0uy9i1GILmqurm/EvWlDVVFbWVFWQ+Tt8z42/+u4Nv5JHsCPV8Xg1/pU1YaRr\n",
1019 "KvM0YbBq8twgnW24wReKj21YnC7W8fFjuqTC+DGi+Ehe14y8lYYJAd597yn3qYcUN1vi+JetJmX2\n",
1020 "fJk5vzHC7v75z1v4/9nNwJ8LCmciyo3QGLJEMiBSGxH5YzlKfrEGMtek5TCYFA2wy5FareQpa+Dl\n",
1021 "kw/USHbRkRRld1kNsb/o5AMb/Mo4BMwb5INpuaPcyuvjUOpG/rxUs5/f08KWPv10y+bNVLcg18uK\n",
1022 "FL1M8+nxLJI41yWVDPEsKAqSopc5QjcIbpH5kAlu8ZmCWRB19oAc0GIs9UMmjgXiDN0onIUcYiIT\n",
1023 "zgJnpWKW8GEKAlookSyaoXwpQSwQtSLd7JviE1dcG4zCek0wisb/fjCKj19jf3698OL8XYRGPmID\n",
1024 "4iBvnxPYc/IM99zoRCuHJzPI5G9PaLdpNTLt/sDL2te0Z/gYorDuG0MDZ4yXjSN8DEmbjR6juKLf\n",
1025 "pKbVvJ+PjdiHMfs9fp4KyxQ/toGlVmzwnCm+jA2eJ4q38T/9Raor0n2hzNhOZB/X54lDcylgV6Si\n",
1026 "cjKVKyItClQ3GW4bInMkCsdXYaEwH1Q379hGzyZwLCE9hXOHO7EttQlgB/PNEfdJ93k3NKal7lXu\n",
1027 "de7Nbt48tsOw8XEoxEuyLPAna87XQCcgthsHeBO0AKK5OUzRHlDw24BlKGw94CHAFpx0rC/cgs3C\n",
1028 "ZZhBTyF23Qb3VpBGPoyEHZgzl1Wvrl4PfvchFHeq5gIvrnIcOx5vGmqiJ9DqAlmNXO1gtZk1RUFP\n",
1029 "oa/aW9A2MdKRM03rbewMBCdHSgp81b6CLJfenKIJAV9VXWkk2VKfE5hU43TVtvPBrKYi0OBD+6gd\n",
1030 "sbA9xLE3gQ2TPTeZ/KUvCyNYfZuxNwV6dn6NOOpZhnZyB5UsWi5TmXJvTFtJ5mQ4cNUZDtwxzeW9\n",
1031 "DLP1mMYSRmN5tHgjGoscP4Eay8wQux45H7WcseR8snlmptEYy0cbjQNnWw4i6cdL25eNPEhBB4mw\n",
1032 "cjNe2uN4aUtcK2FOt2nMCwThp/QIgF7lesB+wFa81Ffdp/FSwakkXUIqfD2knWhOu3FsuwsGvHjR\n",
1033 "2INH0yJLlw2AS/Qxs1soXaTtmQLU1o3ankI7I6LSTajeOjTl11HCYcASwFrAAOA8YPP48unYeDus\n",
1034 "a17PNuztaGmrqtehOm8j4QSK3g7A0Die4NCRp1HmZld2pFI3Doy2PVZwo8Y3yoY4p7iWt75QybWt\n",
1035 "r75SHp+e4auhuxRf41tT6pC0EcYVZ9XvwbjifrWsCcvHbUNyOF716JHWYqjzZ3MyjYSchIzyAlGt\n",
1036 "xDCXp9IA/8fqWlq+3tIivvLOO+/IZS8aeYDtpFiCOuGv5WiC14sZSCzEcEwZSGkOaQY1/Es1RUnv\n",
1037 "1/E2+lxONpZglrGYQpUjCGEP68NKb1x0Qv6NpknTo+lDmPEPEX1PrynQBDWqFYhBiH/f7uiYfQfF\n",
1038 "IkRNeT25jHYqMtrCnzKNo0VoIurLathYDFHUdmISkV5QgbBKRQHbidmNJvMXdDxVy2ubhMSeu5HE\n",
1039 "tIrEeBVVMOfsU6GKcK3Xq7DDQJXXwcKzT4dvEIBPryvQBXWqFSyi42LWedmdSu0zgh5f/+e4qAZe\n",
1040 "Fl8Tz4iqhf9tgdNLp9c/hnpOPkv9n74E21UvgZ1W2gsTmthp4Yf0HLeDgRQRVfhAda3saRMzDbd2\n",
1041 "6KbkSS0JmsyxDJnWoK7i0CeK2saFuUGW47iyV/KnJb/1NCwWwMYqXsYq5gXxZcUh/3pxL1ElOfgl\n",
1042 "akL+oteI7hMlBrk8IsuDZDHygPBD6js9qM/LIrth0TPHRdu8cQkupYS/xfPewZ/3OXreEGQNV3ox\n",
1043 "OwZIT1Dvzzq4ZkVKbma8r99B/Rz1nMbhVr4WdQnbU65Qv1N2b3RZYMx/CPYcZzC4m2E8AM8e6dHC\n",
1044 "cRSq1/U/pIM1nKVpDXQWdh5T4U+0tF7utzCZvxBbkk1opR9gFNeCZJqMK5vpow2mxJNxT6OyIbsw\n",
1045 "3ZjfxZeTiteeQn5HWztW70wVaxN17sp6T7HDZCr0R33WdtbuSUbm2bzFVm2bpmTCxILhDwX1uLil\n",
1046 "E4V2VSNFLpUDlsqRSrNRTJUApv+1yKXtQ+nF7fcjBoGlnd+WaucVD7cn23kTf49fp9qG5LBDwUFE\n",
1047 "Gq8bkmbV8U/NPLWZ/61D6PPUpJA0axJbAa19BLENZrYuasX6opWntfC0Fn7nJEvqpiEpBnPXXtht\n",
1048 "ngWEYTG8uAM/6VzUCUaETixPOl/ozOz+/A/CnBZiGzS9JvpElDc0rwVPchYWocloG9YTyRCM5qKW\n",
1049 "VIT/EMEphYglUhZR8TVhs7yf2jKIIEqTiL4GvvE3DG6qUTlU8ib/1cFNodcrFvTXi2yaq3PfMLIp\n",
1050 "+IPSOfpCHA40URDTa4Ob3iCuaRpxTUUloKnG6rg2oClI7saHMU3H8ruh/NwwkOl5QB/Oby+SyxDO\n",
1051 "8jpgntsIOAfoBdyKXa5zgCigG9AFQrlzgCigN4HFEeSXYbuTHSmkGB68RzFl5rqWdcqo74QShhT1\n",
1052 "oTCk52JKsenupnlNXHxN8Z54X5w/zgUU2YSCLgCmJD5DQNHsl3zOozWTDgYoDu+nhxJlwanO6nKb\n",
1053 "tdhrXdjy7Iyp7eEvtK28ueVTA4guUeUVu51Feepooi0e1fzzgQM0txaINcIp8SJ4L9gjktGJ9bvs\n",
1054 "BUu80ljgbuQrSJzGa8EZZg0V0C6AtAjqTAjkcJetIzhUNON6m/UFfg1jC7g0pVuLZsKfJFnEe6Zq\n",
1055 "CLYaORRSj85fQKIj9eLUZX6GlCppiuV1583LW5q3Km9dnnYh/2zuNs8zLzWvMq8z43OTrcfWZ1tm\n",
1056 "W21bb6PP9h47ztpX29fb6XNBT0FfwbKC1QXrC+hzIbiSlxXC+oLyK+kumVeytGRVyboSfI6WTi7t\n",
1057 "LV1SivBeWt5K6LSoj2qGk6F5qNk8qllTXk9eX96yvNV566lmTeYec595mXm1ef11axYr7C6cV7i0\n",
1058 "cFXhuuuWjLCo80qXlq4qXcdLtn3CblbaW1joxT+fuchrs1cUmc1FFXabt8gsfqWwoqIQ/+xed16e\n",
1059 "22u3ewvN5kIvrTfKR95nf8PnrnqxWzIjIix5KyEYLLmwgEpWr+YLIjNFh5XN9aRFINQ2W/rLuHJl\n",
1060 "tqTqB1P1ISkJy5BWmHediVCQ8ch9kTWRJyJqZdgkr4/M9EYhJMhUpM6ueIHBPg2H6jhXNciphpBU\n",
1061 "YK9THCoRzkTE/NBfJF7BfpFvSHrfJx/r+LEN+n3olEPCf0KPBI9X0vAQkw/6DjCNfLKX/gF7i8GE\n",
1062 "1bQOWy0P5j2ex/8M5B3hf6RfocmewPi0z3oUrRXBFtOnnBeg7VPIhp8U/BIhG45kwtZK57L60UnA\n",
1063 "G3BM2AnoqcCRIa4uUlzZQA9iBFzCAVYTzCNexy7U24BGuKycphhw4I7hQ+Q+TJCrAafoCvXewnYi\n",
1064 "2vgxdopd4EsfaQNWKAcAYApL42g2+1jSqjw8Q95RPNSr2ILfn9X0aD+D/DUvEbjGWDjSE1CoOFR5\n",
1065 "a8UuOKRMwYO8OfoMaRgXw+kKT3EOD3AScAKxISrrG+vFFSwT+NgJw45rSKj9gUAmZo/TxZLmBp+V\n",
1066 "Ly/q6jrq2zyR9orowvJm+03V9qDHNrEyaawKFJfUTyqvn+tid5ZU6K1uW3mpwWLoaPDHvJaqhkCZ\n",
1067 "P8dWavd6csx86JpQ7otWWP11sPegdk1+AP9GvD7zFgqCXpDek900RWHSyIPsP8RBwS7MVXkkfye8\n",
1068 "pDp5G+/kDZC397OyaXt/Hr/OUcHGULLTH2wmzB1MzQ3RJmOnJTV9MDU9lH5i+rbpIrlPSVWdfuW+\n",
1069 "2sFUbSj9aO3GWhEZpyYOpiaG+hv572ot/TfxW7vpVukRxFd6B7ChGyvDenlLcjbvI7MRGHUbHJqS\n",
1070 "9bPlJUJ/DrsiVcyul23XpTX83fTb4WUsJzlCqdnkMCVVJclot1H+YWMoVW/pb+Lp3RXEKroOBT7Q\n",
1071 "LXcgcofaTFyfmO/ID35n1lP7EjYyDsIg+yAmvFdghQSzJGkTYB1gB+Aoeedga2AfIIo5cQlgAABi\n",
1072 "ivS64Gb46dA2AbZJRXlzYOD5ur11h+v4gnFLZCfOOk9FLuDPgcirCMW9C4ukJqwDd7bvx8JwPoJT\n",
1073 "3YUT3j9N5rAcJ94HAKdm4AqwG3B8Bjx+Zh6YyX9zeiZP2DULTXYOKgvQz+XNOzgXK+WlEMG3III7\n",
1074 "8PTk0v8t/ahBzEEIYT+EsB3PehJmWevKN8Ms6ygJBA9/hMNA1DfZ1+tDWEVfRgD7AFsyZvbSBsDz\n",
1075 "kMFAzRGKLE3RrEFXcgEj6G6EIT8eeRPP/ndI+D7gTkiBREGPPxXy2N1+EPJIIGEp5PEB5LEMorgI\n",
1076 "ODgVLhQzTs7gwtwxY98MGJRBDgOAHYDtkMg5COMI4A2ACmKxAyo52OCJUyq6MiYLgVidalwX1+qu\n",
1077 "39FlY4/R7v7zkgkOj8/SbnI7TNaiCmvzFo21yOfyVrv0oYo/r46FA36Pp7HT13F3Qbt1SrW9qsLh\n",
1078 "L9sQiCQm5BYVWErCrd6OBWb2VWOwzOFx5evKNPmuYrOz3G3Tuw/lOm0mZ2mpvrLK2uRsm1iXdLib\n",
1079 "aqpvqrI1JcpCwdyCQImnytJhaw03JO06W3GgKJAI2mMBrG/auJ55guuC4GB7ERxsijGOHLjENbpz\n",
1080 "/YJW3rO+rB3RGhbK/HCfKZoJDkhMXHM1HTIN8mVxvxEEN5Z+M9dcX8CEowQKuaxwtfExIC80ntWB\n",
1081 "r4zyLBQjBNqtqcnUY+ozQbvFcltvKjAFTVx/HkfTFoscz+ykTYZS/R1lx+zjF5W9hiiHN8n/aV9G\n",
1082 "3yclu5+pwFQvxTH9vAYAAYq0FYBIVZn9E67kqkPpVvVMdUY1IqKrqx2iyK6KgckCIw2ZR+oxX0eJ\n",
1083 "fnPUZInP0WBdlLRYXkG54V+Ka0VZw8GXGaJ66Q/QY/QqtoIxL8hb2JvDv5zNvMM72HfFxz7+kvhY\n",
1084 "+2gMTYpTXct+IJUEsG4dwwCRhFfho4DnruaCIBqIN2H4SNaP20cJIWaho24cRwhBHBCZhyZ2CDot\n",
1085 "GscGgWhsChuEndggpPPI+BW7PPz2UvQjsjDKMi0QycIxABGQn8J8/SGgAAvuHMAHhZmVx2GYLR+G\n",
1086 "9+x5wBuAw9CO3gD8AYDY59IpjEgfAo4DSG06DtiPEelVwMUsUzi2lgderTpddbEKZMvVfKFxtPaN\n",
1087 "WhxZ3Iq69mVDXRzNslWczPjppLVOJ9gqfl+oLCvSpzwXcHx1CpUhb3DyAP8I1TqdDb5+AZU5TUNm\n",
1088 "hp5C3mLeh33uN6rerhKvCbsec40NeCFH/rNFVn8mJojXFAKICoUQ4jpEECzG+4pm5NfsXvGkoBL+\n",
1089 "VfHPuIKGbBy1mhJEUmCkK9Cvjapirn5fvfs1jhqNJQvBOtorLBFWCmuFTcJ2YUA4IpwUzgtG3vQz\n",
1090 "rKS9oBI0gZ62ly1h6C1aPpKzfTBbewPdZQu2AYJik9gjqviaF9HE5XN93mWoXcEoI92tmscrlN6p\n",
1091 "2q+SjX5a4yzUnG8TT9jJPhYd5p9Ufyn62WOKT/sZ4QWhWXoBFtqHALPA+oKABWnEIUQjoO8WGaDe\n",
1092 "GUZg274ICa0G2XqWCXN5nlV8jeVhd+1hav1ofKKz2ahEENhZTLKz9Iv14kIlQohMqJiNE2Ifkhaj\n",
1093 "CyTt8s9KFfdLYk8yjt09g0ZRqgYPRao0JIceIoUCNhqMWCNKiVTJYVUrayWrpb9AJr5ZD7s14jm9\n",
1094 "BKqsw7YT8HA5j1n/DxTJBVU4AnDBYe0Cri5iOfAWYCfa/YNo5ofdJ3Bg83t0Sw1ObZwIjTHPvdQN\n",
1095 "ma1DKedRyjrAryhnwO8BGhwyHrGBidc+aD9r593OhsIoisz5bDlbAQc4DPS5l7lXu/ltFISjgJfE\n",
1096 "vNaIo7wxIscwkefdMUFMdu/8ePjWJYsX28O3TKqdXRqyN3nroiX6nWzm8LstLczWMi/c2xYoLou4\n",
1097 "iv3NycLZFGeKj6OTxD7BLZzewzQ2dc1ogKnMGx0TZwqmmJJFIJNLaHDb0Cjew9MJNvzAthhyPaR4\n",
1098 "DtkpIIqTXk/hoLQmE8xcID+gzG5bRm0kJhFMKYVyhBOTpV8nM2XZBrG55hykyEeWPgQNXg3VZzlg\n",
1099 "A2C+ha/yBqK5k3N7wdONm5ZZ+IITbLciAlDRqIKwvDSGkPwiXGLxdbn5hWarz6yqnGirqnDefnv7\n",
1100 "OrZl+D/d5fm6XP1N1tzicIAFWr78ZdlefKRYTIjvk13Ccq7zpl+oe7kO3HBD1zUaHzUVh13CGH+8\n",
1101 "64a1IbsE/WeyF1fMES7VsDH24LJt9hTALsB27Pptxq6fbBMubcKIvoM2u7JRHaZmQzvsgj68v+BY\n",
1102 "AXTm0iNwoSJKnyMYwrHiTx+rPoWDv4MZw2/pVTpz3IyZu4m8gshYklyDUPZTKHuLfiesIDabdkB5\n",
1103 "3YGSyHx8B4qDu55ifC4bO+yvPoYiTlcruZMB/LUG5tZPNDB313fVZAzMneHQBPunGD+I9cMbSgNO\n",
1104 "/TgL8x+hb/h533ibj3Ex8XapLKiqgX80he3p1/Ilxn0Kw8dC4uuAZxz5IWH9J8WCZRiDYiHJHaOr\n",
1105 "oKW/ii+syiz99WplaWHh79iSGeHIeRojHLNUyvZ6KYuFtEGjnGAMga8xyhNyo3zQoKiCbkY8GFWV\n",
1106 "YOVJVYWkxXweRcCsWvkM4QQcdrXYy3odqg8ZbDuxofU2rh5E34VXU3pr3i5sJ2hwxrAUb8fBO/PA\n",
1107 "EttK21qbSj5sSC+xr8Re/0+gI96KnQWdy+XiSwAKV+XikD5Rcq6Ev+rekiWgwDiBl7oSgJAL0o+z\n",
1108 "jBjnAVrsPCDqgrSK4i+gka0CXMDh/kVspbwFOAatSQ+Sx1dh6XMMmtIxMDh8OBFt7xQeUI8HfAMP\n",
1109 "eAGPdRrgxlOuxgNuwANuztuBB1ySOTpJr7Ktw0BVgCF5Nfxh9K4CPM18PN4QoADPlQMYgp31CSwl\n",
1110 "5wH6UOHVgOWA04AcPE4f6r8asBxwkQCPcyqQeaYjeBwdHucoHuc4Hof4Oz7iYItkwkmM93p2jYae\n",
1111 "GBvty/vDSk9zdWHXpAmdztay29uqpzaV28prC1SlDT67b9ItdTMeKJme350sjVa5ShvavB72ZJ6n\n",
1112 "wdvcGvSXNccKQl21JRMR0VhbHm4pr58+sahzmitSb6+c6AnGKszkD107clblVPyhk0KnyphqC0l6\n",
1113 "EABW1fPekPNprtCgLh4kJ0bM9Gqa77VDSB7jD01ESRZsTKaq5H3IikH47duG5InlBWyQtML0uz7j\n",
1114 "EFbIC8LKM1lfJW+bINg3V2eT9JHf1jCEfOI8hzhIEtpSbXyUbsPhk3QZyvRrgMWAJM6cOobwZeeQ\n",
1115 "tGZyZpzOhtsa6/t2td80+a0lyW9a/1n9pkvoUOs+NIQzAEsJ7YFaQgMzLYss92HSMls8Fq5WlhBD\n",
1116 "KihRpcK6EgrmgkEBp16tCN5baWlF+a9iPd0g59IQwglZ49CAudHTGGpUUSbtg6l2WnB1DqY6yail\n",
1117 "sYx378llvWVLynj39iPm8FyEQT1HvHIAJ0VFBZxEu+0F28DbuOoGucB56oY4fDkNuAQ4hvO1Juxf\n",
1118 "rAbsByxvw+DStqsNPtttp9sutsGPog3O3ZD9euxx7G8/hj2O5bje2r6rHbuQ7ReVbaAVUi9O7NZ2\n",
1119 "kHN3x5GOkx3nO+Dc3YHq4atVgB10Uyfd1Hmk82Tn+U7chLO97s55OOfb0YnhAk+a7i6bB8+7GK5P\n",
1120 "eS/A0K4ADzqfJIBnpEeeh0c+GRz7yANHmk42nW9SyQ873kO8UgkJM7bvakcjll/VdW1wJH921JH8\n",
1121 "4/6CqkSVp6TSHnInq4vClY6Qt67eVdVYGplmixhrq80lBeacgurykuh4X/P7KyoLKmxF5f4Sc3GV\n",
1122 "29toEPXNgZI6j6VqQmlpmdFWaDIWuczDJaO+6BWsiHXzOa2e3Su54VpyFotLC9ayKcVSmy+3bKGM\n",
1123 "Sbf0Aga41grZBYRWfRlTbqm+gjjj6kOSs56uKkAugiy4Mg2eqzTOCUT55OCq6GYe3gmwvjgDYHke\n",
1124 "edKTY9GsGJDDAKjg9gPzkzIcxeTKN+ViIkyFh2R3PCcLUyfAotnroU7oDcEd2s87gd/jD/llX+hK\n",
1125 "ayNOJWW6GpXC6HEyw+OR1tlddj78v42hfh4G/RMYX96G0noK49OlKrSfydjOCVhjsCA8RbOGvQA/\n",
1126 "+yPyIcIBygBRmdMnqs6BdpFIil6to9H9v9BAHrtxe7BPHNsexMLyiiLvp7YAmVv3pJhkbvF7Qolw\n",
1127 "STILfAQ3w6lHpuETvpCy42gPjzILuph76Npjb3s2bM6A2eAxhAw8TaPElMWXJXx8C9EulmySsgxG\n",
1128 "KQ+RU0yTukfdp16mVisu529TSBUcAs/LX5q/Kl/D74nZum3zbEttapDZ4qR2ngrM7PSVuls9T70U\n",
1129 "Pz+a+fkAwnufxwH26nwU0Zw/JX9+/vJ8NYpTDuPUC1XEQEpuqNFYRA4T6Kf3UK0yOT2u/Mr8/Aqz\n",
1130 "y6Gp4R/LnPyjtcLCP4pJm78kPy9Hb/bY7JUl+WZ9Tp7HJusBLKiCbUme4GTbUvkhSa0BFakSbZer\n",
1131 "SSFsgW0kWwjF8oyUqkfhm6iBFizNhNXGNkBZDtemFF9/RasyykTnTJknFaJwaQ2WLwiqKc0CMXH+\n",
1132 "KI+jmeLGclU6hNe3puAa9g/rEGzDNYOw53aQC52YC0164Lj4pngJJgbwdEo7xEp4D2qV77Rvai/B\n",
1133 "ccWhrdTy5IcheKP8Xdw41bjAqFqRThinwQ/uTzAWMBiLjDU8UXoYxgLfMcokEQ6q2Xt2mDzYLfYy\n",
1134 "O280FrKuMjyv2qs6rDqhOoeoVRQ2bx2gFxPoETW4bDFhoAm+qjmtuajBq0YUEdkfKmmQPRVQS/77\n",
1135 "+Ub0UURvTb9u/BUqhRRYSqu8FPgzYiMmD0QALVc91yL+TeBvxJaFf/VXCz7+zeMt69kUFmQLhrfT\n",
1136 "v6eHX2Et0eGn2JIo/Ex55/ktHzPL2FelQnAvLabVR8bcBwqrXk27ptbBlDVE72TAbPVYQ1bVin4L\n",
1137 "baj2e1RXpD956G6ZNEMYPSy9egMJ4WtBlPQ+0X7aidHjACTzvoqsaPpNXA+wUDpfOUil8h25sLt5\n",
1138 "GEvu7wOIAeMpAALLY95HjARpOdE2QIqIKsVf6ztI6KOlMxbMR7O7JG/mX4IdxDKswuiUaBVG2T8A\n",
1139 "KkG8shbrZOKOjOLjKlytxADYDObIquLmYvipH0b25wDbAUsBy1DafMBFApT7JuA4CgfttrQEBb5B\n",
1140 "myfOTNEoK73KtQ5GtmB1KS9vZPKxxTVMQeXst3yadFvK3BaHv6E4Ot0w3fyXt9TcnPAWBiNFZ9gD\n",
1141 "c5jH4gvWFpTUlVlbIvqZC1x1XXVVnS1R90+VebKc5slSdpfMt/UCOU7iGc+Ca+ezUW7NwuzWiv3Q\n",
1142 "+8oynZJCQSu2htdjx3o+G7QzhsCtMkUWefdKGqT+SpQ7/41JsTJEiOmt6l0wg72E934RGtIlizLj\n",
1143 "SYux4WSH5//vcaXB1eTMTlQaNFbiGBorhRAKnF2SX2Hv4jXJ8kPtHM8PVQijjrdR1nlo/KP0WR/g\n",
1144 "isJGUlkghkrm6BwuR8ARc6hXsE+gfmLdN+Z7YuU3InmSY5lwPR6c7x7hB1KRCe60RUR+2++WObhf\n",
1145 "GMPBncLLGgSMQG/dWD5u5ZLZrMkyKY3ttZKK2JOkl7An+wPVW4jhcUlFIVz67SIOhbj+gsXI1NwF\n",
1146 "ueKK9FTDAgMX8iraFIHxjOIPsg7tvw9dqo+vKYQ02PXQArBlsip/HW7B9km53y9zuvsp3IuybS6z\n",
1147 "vbOnxhBsG0vqKxWK7SzBNqsa/jjQUuUgiu3hb9ri7pERWU50rn5C2ScGH3Je+v6yR7FkTpYxiqtz\n",
1148 "zX2fo/sK0ovK7uP3Ddzve9S30YfgX4j6oHCdyr85mP3NHfSboPQCF/XAa2Vnyi5DFyHquRdgbGJu\n",
1149 "4DrKaw1nGi43qMbnMVruGspDJy2qyHA6IC7zX7P3R/ZynbUI7v2aEE3Jg5h2GbaWQ2Tj6Sh3lLP3\n",
1150 "h43TGmgPlMPrvH3omGaPoGbqGmXXPweNHCqt7EOHNj8gx43jwzosU9WMepxAi1S42w/IUfl4ZyS/\n",
1151 "ci3gvYzt9Gs4VwkD7sfETyT6tA54AhDCxxSuLDkZ29pxXgvZZqYWiGQf8cmko7B2364egDn3CfU5\n",
1152 "tagEXaStUqEPvPqyu7NqxWjEsz/A6gQRonkjRHQz/kenduEPFlniinKvKmLj/zHn1H+e+S3xW9PY\n",
1153 "68Mr2VcERVbiK1xWZvbkHr7s4bJS0SLSPCTdj8F7FlwQzprBusAfmeVRVbdj9UMcApsBJwC/Umzx\n",
1154 "+WJIoyZjhjcxdLwD0+etml0wfV6tWa/BuQFXzCG1RZnYjDDjRqcCAbNBRWulPAs8RGT+7EF0KMzB\n",
1155 "0hOKodpC6WVAK0zWnsOVBVdy4KxrKPUz+9ASM9G0+jqkNZ8tx1b4g7A3lqPW8Nb6CyaTWKsGJY18\n",
1156 "73fxCA/iEeZrloOPZS1tvAEoZNEvKMgMMVvzNZhRIHagJViyDBn/k2LN43qisdMo09lSeIJ5ZJIG\n",
1157 "EhcKOhiEGIib8BQmzzewiRLAhkSAi95mi8j/qWjVo7rtHvGLnV8U75nx5NQviF+Y+iR/k19mX6B/\n",
1158 "tezR4Uf5m2TUcX7BrwziT2UPHqxf008I22BtdQbL2FmCTLjAV7J78fLuA/wQQOGeLHAoFoeSprCY\n",
1159 "FGeJi0XEctKuSJoR0ek5MRPPScfnTkz/r+FZZsH15zktnH9UY8M7aIbS0Db4wLgAMYkOao6jDaiH\n",
1160 "MiSdK5KG0VBgmoWye2T6rO49GHQKENAcwJtYrCZ1oDrMBIJTLxxAyK/FOkTCGUqaERQHca3kkDm6\n",
1161 "hUlTq17mIkPAHO0KJRaO1JyjCFx2rpRm4rAMSpBk5lcDLxheNrxmUC3McG8tlG7DsdkJwzkDkX4k\n",
1162 "TRtzn8tN5crBQ7V8wpuVuzj3/txHER8SjkeSBTy6IcATeJm0LYZYQRnncATMGHPcmGmoFC0IDTUn\n",
1163 "FwFUpd9j8IgCenIQQybnIiKJxVB7J6ALX6lxpRLB8SzHlqoCgCw5jbU473URVQesi+VQHrIpgKRV\n",
1164 "5ZDujWM2tEsX2mUfbPJOCRfQSpqIjQgNwo8GgUhaA7IGp5KDmkpVcBt4A68f/EhSAQAOIFIVXteU\n",
1165 "bISOPjTvD2HP3pPTByISP8Q9GfAHyPzDXCxHTqLsVcI6lP02WigqI92KZ6HYCyexwF2lXQc+JkhD\n",
1166 "WpCDKJsRVywCS1ud9192L3jsC7d855UFz2ye+9GbL7zw5kf//u8Y3ywjFnaC94V8MYklHW/wa9Dn\n",
1167 "t7EX2Mvo84vwjPdm2UT4OEgDXNZ9u4/iZ+JqX9bD+wTgV4LiWGO2IEyUtAUrAzPGv/QTOdvwpkZo\n",
1168 "8Jcz7IMT1y4K4AP4KBtio4micljkEzmu/1EM8UuAKwAjBrZ1GWNHaRaH/nw+EDdhb/81rL7uA0Ab\n",
1169 "G7MazbQoohREKDpBm49aoM7S3vHPcSfgAcA3BHkhynVKraXfKF6RT+V+byFtY2C/cEw4hdC41Dam\n",
1170 "4BcXs27tH2JWpfmVGqEOAFd0ya7mTXev+jAmtL2aw5gGTmrOYyh1ogF9iCPWXbCBbLL04CCQgo9c\n",
1171 "yJ4GHgCcBvwRkANpLcBVDwRDUsjJh0XYL1CV1wGHAT2AQpwknNJkFstFxO6VJwudKy2AUwA9cp2S\n",
1172 "LWRB9jUdB3wfANrYGB+FZWrnGG0+xFSRD56YdcnRdpPZY9Y5SrxBc8WhObPZX38sRZOiJmmoDS5g\n",
1173 "b/J1DrVBWuf8TI6x+BBWOa02WuVkvz+Y/f4O/v1UPizaXra9Zjtju2zj2jDuTntsIRvvQUmoURww\n",
1174 "dFa+XPla5ZnKy5W4B5RynspQJe6pZATyQoqNDPN5vk58RShglj2W0Vi+g3K0JOg+96Evi/K4zVMK\n",
1175 "hmgelCknFVerxTQdk8gEixJ7IndI5gtczKE/h99kyKWgEltxUINIxOJCOURFyjQo5VlylZ/ZlOAP\n",
1176 "Y8KhG6+2N7baKa6ZNYRFvVFnV87NTEMgejDCN13SU2r6cf23cCQKPWXgsP6E/pxetTD9Hf0emCno\n",
1177 "yI/eSsTDdOYs7aMh5wRGp/McYo0Bb2NEhe0EFcJMZPzZG3+re/oL/37rv/3brT985Gndd77T850z\n",
1178 "NxujrHf4e2zu8O6o8eborl0wyxJcHL7Jx5gcdk4SsHV0H5rbZQB8nSQPb3jyglX6BgYZiqb4AOBO\n",
1179 "rEVgLSIq9lSIZ5u2Mx+WchHWwf9ItyDp71k/bIozgXIhO5nsAu9uUMoFRV2Rtobr/+kW7XRsAyxE\n",
1180 "0j9p/5mPmAOyHRzvus/gHd8D+FvAIxhVp2jnY1QFtRwqyVczulAaUxxoTPBm4eojhQGHAPcDzmDo\n",
1181 "fgJwnyEz9IyLbpt14NbLx/78DX4HY/yXhScxxr8P32G1YBd8fCUrD0m9gJWAc4BXAD8B3I57I0KH\n",
1182 "MAccoypLv8jz4++eokj+ADCELaUWzXTNbRrVijQimfNh5h3Nn/ifAYOmSFMDptWHcOcUjbx1gkUg\n",
1183 "8XDBso0vtSBjZQVdoA1CjD3aPojxdJZx75IWrcalgSUbVzcayZhtw/CvWTFffuUPX2F3sO8Ob2kJ\n",
1184 "s2UtvE9Tm6A+/4txNs25ik2zf+R9UUuxjwJsZcobklq9vP9o1FfgasQX33zeQMx3c9I8y7zYfL/5\n",
1185 "UbN2ITko9RdmDpzHbTVlQrVQUBN2heKZyKfG7ytPSZsQimXeOvI9QgdYB8BKIx3NmYxZ6yO81B4s\n",
1186 "Y5oBGwAfAXqydmMfkd8aBqGPyGsaOwwgy+ZS0zgdTv5nu3MAJEaaYkcxPhUPgM+RfG+W4MxVi/AA\n",
1187 "fdhLyQE/wq6yA2AozC1zl/G7d/kPgMGxEKpjLgKK9AWWwZg9J1CIuCKI7rWQIlpDi6MIYLK/nBRF\n",
1188 "LbuzVV0P/brXsQQE1X0oehmKno+QPr2BJTxHNsYIgWxlx5mlTRKZM95RkZNT0RHP/J3+ZxPz8yf+\n",
1189 "2XTlr/i1Sbctq65edtukzN/2yff8VSLxV/dMzvwlHculvOsw+/dUZUh6lI/K/bkqtOH0Ws0mLIdz\n",
1190 "SeeSuaUtg9JKDLFLER34pOU8ZsVbLdhYedzyLcvzlr0WNYwCQBpN21cbOZCBO6jTB9Pf8jzvEemG\n",
1191 "siF43fGLanJwDA+mwsomJdmmZFqOm39wk3vHBLfs3pGawJc07IqkkRO4zs1Vtvdg+SXoLfAnM8lf\n",
1192 "mELSIqxtKQQmIiEh5NF7FuxhWSyWMgvvrW5Lvw2GLu4J+IEzlD7kHHTKM4KH1KYKOkUOkEJfTaPz\n",
1193 "KujBWwAxLHmex7uksDHnAX/gT5s0wVgh4Iq5ul3zXHxhfw67lLfiwCZGERYBsKYZWBVeF94cxtbF\n",
1194 "Q8gwigw3WTN5YddF+hNlaHAVuWpcCdc01+eQYV8mr/TukoMwf4A/vHRnmCesDK8Fm+hmfk3eE7py\n",
1195 "XTn8fFwRnVc+lFACIwS8sQiMqmP8LwVbdLHfuLqqN/lYkXX4XRVj7+WfMs/pCXZaQ8W3R6Ozm336\n",
1196 "afZ6xlRd9ubCr/6f6nmF4l1W50CTL5hXlBeb9/nKooq6Wl/bgmgsr8Ts9zZ9aVWBRT4H+kD8UNir\n",
1197 "Wi+ohDvw9hjCZbON7Dkme9+eRSRW8khOGkYDb/P1gllFY4wqqZqlWqy6X/WoimszBgSTl1M0UAKF\n",
1198 "L/CxvAAUjHSWx0cvVcTlzf3cHQnV+o3yHk2Cl/8RlT8XtslmbHPCpZscdMdGAc+GBv+EcOBKgEiR\n",
1199 "lyd6RJQHT+OViTs+J34olzfyS/FDZuLlaYXHJC3mW8Qjh+IoDMkEJjkZE281HdZczhzWSKKGljca\n",
1200 "Yri6TAHhM/TcamLGQuhD+Yll4h5G5/xch8WZmSgHLZbux0JSVGkoDAaD9hGLMFP7nDnt984SP7zn\n",
1201 "no3j6riG4l5KazCVPcqyrFyXiddpkXifuEZ8QhwtfcwmFF+UQb/mj6OVaTbUFNkWCwteR4Y6MpnQ\n",
1202 "C3VNm1UebFHej7W3mpG2p6Fw6KQmPTfrXtSQC/Ee8Fr2igbhLTnu2R6Visn7Ppqh6/iAQ/xPNE/q\n",
1203 "Fg0HcObIb3ar7vvfM8fPcuaoUt3ozHHkHJejQbVcMPCVwkKsagWM/0mb/KI3auWdlEHtWW0OH3a1\n",
1204 "FjgvGLGGTQv5lnxxBb8z//78R/M35j+Xn8o/lD+YfzY/B83CwTuPGWt3HNTl4P2PofEIjLl+vtjl\n",
1205 "Ksa/Q5kLVdTu8djH/EP8VpVLGFHd/InxW1Wu6H811uvIOXGYP/9jgklwCnt0DBuPOoUkC/GkeAOQ\n",
1206 "Va2ILHRmUM+eNGm2ulYX9/vjOtVjrV1drQH+P9nn9VfCKdW3/9fn9f+XPq+qjhv7vIojx/g4Oovm\n",
1207 "Fp3w7ZQ2RGM9kQ2l4eMjwkwtfVZ8T6G6yEwwY2edT5hs5A3Kgfs0azRPaOhXmpmaRZr7NPxXaoWq\n",
1208 "jf9Kl9lyHNSd1dEUpcaUqHCkyL5FCHYuD5Ya/u+HfL4a3pO4E5PWRj4fCF3isPAPqjt4G22gPdkB\n",
1209 "kCi9LKhGGZSUXj4g93oVSsnJ9J4x3bYr21vrM71U5k52C3tHfnL98Zz2w/UKxQhoNZbz8fz8Afxu\n",
1210 "sThROCe+y39n38NUKvmsBDGXBZG4K/mq5nsY/N89IHPkmDl8XTzG79cK5WNCJl9z5K1BJ46wCF/Q\n",
1211 "lJtZ4VTmGf7+L9hR8djHTeLjHx/4fzYvJoR4Xv8o/lioF97YY9F41DV7nJpCjiGNwLFKo1XXpGFY\n",
1212 "IC5MFuVoC7U4LIfmu1z7kBbmB7u0B7Svak38W63FafFbopbJll7LEstKy1rLJst2CziBEQrLco6v\n",
1213 "x2GQ5BqETWKYMKLI2ccr7LsmZNJYipCUz9JvEK+kTxsuGlAVvaHAEDRkWPZXG9Ybthh2GvYbjhlM\n",
1214 "GK/g75AK8YU7b1rljZmzcVltcTlg9Z5x2FPOVR0RB5MmdIVcgc7bGhtv6wy4Ql0T/nQ4NCXijvQ9\n",
1215 "0Nb2l/Mi7oYp4cN79VWTZkyILmjzVbYtaKydOalatzd+iyk6pS/ccf/sCRNm398enj8larol/r+y\n",
1216 "/X9Vtv8bv/y/Hr+8bOQjMZ/LrFD4CsyHi2Bc3K/nMnIrhHMQmCwOM39O8zV7Ulk6H3wwW/pz4J4y\n",
1217 "iDWodVAOTtvvFK8kixDEOeCMObud85xLnauc65ybnTuc+5xHnby5nnSeB9lAgcpMekClNuOLIlsk\n",
1218 "Obz0wDGHmG8tyS8pN/P5ZzL79XRDkd1p0OfYyqtdrHp4KduaSAy/5izLzcQwGPkt28b7WrlQI/w8\n",
1219 "VRtCLIJaouHkarjsimIbgpemiz9vNl6PzdJfobmSfrPiUgV1worCiqqK5oopFfMrllc8VLGhAgwB\n",
1220 "ByperTCRpUtwUKrS2KyZmL/jPBdo7U9kRiL2cfuLSRDFruJAcay4u3he8dLiVcXrijcX7yjeV3y0\n",
1221 "GIIoPl9MKj1ifqZPV16spN5XWVAZrGyq7Knsq1xWubpyfeWWyp2V+yuPVZoWSlWUN4QGc4dGnTcQ\n",
1222 "s8r+T2RFqXj3RFwqeUXhiEbZtkR3rCcuunvt3lBReNK8uXlOt8k+wSUWTCt1ufxN8apYa9tfTKqc\n",
1223 "y1TVbRNcnS1Tn+3d5K6w6fPtXtHrDzW1/Kztr2UZ145cFutFl1AkVAgFUnEF12IqsPZUmFg9FTTz\n",
1224 "Oa4iu5MHgkAjdH7HM4ne1tv8XlcolgwkFnX6fJ2LEvFFnf4VrXPntjDV3kRzq8MXKTfXTLsjHr9z\n",
1225 "ak3VlDtv8n29peXriHtTJSwTX2RfEwJCTJgibE5NDaWmkQIw1SJHa0b/D+J9Bi8F6X0GC4NVwebg\n",
1226 "lOD84PIgoo1uDe4KHgi+GjSR+Vi7hr8jbbuz3d8ebZ/c3tu+pH1l+9r2Te3b2wfaj7RjbG0/1y4u\n",
1227 "FPY0iho+ZHvFGj7Ra8jOyauE80rVWFI3DaZuIv7kLj4mVma8ca4iJpV9dXRy/HddKf8Urcz6mKOH\n",
1228 "iy/afRPLSibW1dic1RMipWWRSrvNFykraQzV2O1VSJnotzdXVzmqAl6zxRuocvmrh4+bfVXVDlup\n",
1229 "3VAbtFcHvVc80aDL5vHb8v0euzPQ6IHjg6M8YLMFyx3OQLTCH7UVl5vySt2WhkqTp9hmLizL9zdY\n",
1230 "3R45DtbI+3yB8GMu42amTsVDqQRJOE6m+7kkYQck7LjkIAk7Ch1VjmbHFMd8x3LHQ44Njq2OXY4D\n",
1231 "jlcdXMJ8RMjnnc/SHyY5h51hfzganhzuDS8JYztoU3h7eCB8JAw5h8+FeV8gJRYKWHAwFQwJ/N+1\n",
1232 "FKfkf8072h4z3oaUryGaynLig0ifdl90Uy9yF7iD7iZ3j1v2Hlzv3uLe6d7vPuY2Ybe+v5F6Z6Or\n",
1233 "MdAYa+xunNe4tHFV47rGzY07Gvc1Hm1E72w830jGB+MW5E7XxKvsstQZx8OMW9ZRS3h+T2hqpMjd\n",
1234 "0FNX3+th1qquid6I21c2uSY8NVrpzO0qmhWuiHitVm+koibus7C7Y3+9YnrlpNm1NTPiFXV+k9tU\n",
1235 "veiWqNteU1zqiXbPmvMFX8xdG/eUttSXhnvm0Fh+50gN26TKFxoEB19b+NU1wp4y0cHbaJ2oV9eg\n",
1236 "2jSsomZOp8MqG1eT1zyNEdGJjXzk8Mttkm1yWPK4tq0z5ulUjInOhrAjYMsz8SStKU/DRJWhaILX\n",
1237 "UOgwiWetVqPZ5A7U1ZRphvVl829pdhbm5RvzjBOaI1oHu+xqaW0Jl2iMNuiqH45Usw94HfXYwdcJ\n",
1238 "GB00XpUuELPZIszX/t26gjuefan1JJvLCxxOq57EcxWOVIvt/DcGwUFcd/rQnhwRyyWNqMVzuRoZ\n",
1239 "a4TVEit3FLIpw4dF8/Bk1ji8n50+GWOH2IGmScM3D0++CXl187z+iuelE7w8H64VcK2ECPX0il8/\n",
1240 "DqCFPVqRIWeNtZzPQOVWsXV4arsYP6nafaVXdeFKQYbj8qfst+I7gkbIEUKSBpaQWpEmeT39kSOq\n",
1241 "CDBK4t8IavqG/tBD2yI2lcpmY92tu3a1/sPx9es3eNk6tm74IdY1/P3h77Mu+BlRQeKP+Ejn5f2v\n",
1242 "RmgYncf8gyl/qN+pvoKJrHKov1jFK65iPi6YShFrSrX8ELHGiCMQmBiLRmNYmY3a2dMEwf9zuPgj\n",
1243 "Mv7vZ02NoknntFrsueoJHs8EbYNuajQ6udDPJ+SXh+9gPxoWHuzoeNDaVGgqsZpdNmuOr742ou9p\n",
1244 "624pa/SW2+wT94vLP94sPv1xA68ytclbRi6IPaJGsAm9kk3N5aBTY7KEtqcflEzyBxv2rCRr9oOD\n",
1245 "r1ONoT1Wesm5oo4PsGRKhA0DPnvLQSN1GHL50MrbjhzivjzmUsLbs6rpEyd9a2/nH5n75omtTx3s\n",
1246 "Glm9sejBlsdavlm8iiNE2i3ME+eybwilwk3C7XvyNGZ1jRJKz2xJ1Q0Ke5pFCNIuGjhGxGqOboz3\n",
1247 "ROZHHPnXbLSlIrQR7wnxxbMckw8pLYOpFuzBjd3p8o7bA3Pc+CtxrspaWlNaNs1f2VVUEdRM4B9r\n",
1248 "S8unVPq7Snw+XQ19LJtWqXyrtpTgW3/l5BKvT1fLvuFu8LtceXnOeo+7IVDgzMtz1ZXt5pfZxKCS\n",
1249 "SM3sFkHL35Wfa5C5gl/S6Plcrs8YCIqEuYTGIWGPHm+Fz+yNlQ6NxqHh3e8W9sHwQvad4Vz2AQu2\n",
1250 "vdT2zN+1LUkkrs53gpSTzVcS9WQ6o6d3m0PvNmdc9rHGyspGjYNR9t8dvo0XwbO/p+3vnuEFDP8M\n",
1251 "2fMxZf7IWTaTfPFyBHiHIqijl7nYDnIIGvXv+f88HkWWX+BmmV+AjzrvCmfG8A48lk2/jHQuK2Ek\n",
1252 "IL4oviKU8f4+g8JEY36z8fnNlpnsyNr2upoI+TRgGqxgZkyDKhvFu6Q/fMjJBJnmA0E0FijXeVmE\n",
1253 "edH/5V0mVq4SX8yGnLYYjTOGN82YyyZOZhO95fl2Cj89bGeRraMxqC3GnIMHxVc+bikvLKZY1GwD\n",
1254 "e0CJO/ZrcYdqPX/rufR8b7Pm66ZfYN7rpl9khWPS78im/5aVU3ovF9Zeut8o3y+cJfmZkM7lZxHK\n",
1255 "2VekonJogTBWXlMus1iDAOWQYuKsVRG7rInMJ/LAjA67hnIKLLsIrn7bAIJ3XNC/zFso4x/KsKHC\n",
1256 "2BVowAZ2RTI5y+SzvH6LCC0Th3J2OogrVLEVclSyFdJTOJl4C/A9QFP2jO6AWjG0UVgoFQ9x6QCO\n",
1257 "ZclufJ9iwbZQ2gp4C/A9AMWBJTcrCtjqB+cqRQ1cB02zF8rteYAfp8XrcNULj4h9UHgPeck5BHWZ\n",
1258 "nA2A0YW6bAI0oXSKAjUVsDtLvjoVQFGfDqD0uSh9CnmJoWDyXO8GfI6XFBv134J9sZeP2Nasm7r3\n",
1259 "2b+dvWqm3z9z1ey/ZeLwcM+UKe+0P353e/vdj7e/014/e2kstnR2/W+44hKpnf943/wvz6+lNrCY\n",
1260 "v2svtQGT0gZ+MCb95mz6u8KxMemPZdMvC8fHpN+RTf+t8B80XizmfbGTt6VKYd6eAjVmiAIY22R7\n",
1261 "5Thdb1yvzJwD73EwJ/8ZV+fyGTEfFfA/hYNSpcpynS5Zbi130H/875h+KXaO6ZSG4TVs3/DX2bzh\n",
1262 "XewRS6ZbjumRhlzxlfbftA//rj3TJ7P96B9JVnal35WPSX8sm36ZVYxJvyOb/lsWUtLd4j+KJ7Pp\n",
1263 "v2OerAz/gvJ3yPlzKaI/UjqXITimHuQSgwWSRZlC+xlfu2BKH+pXqzNcJTm0E2yk67zBqziIx/Nq\n",
1264 "Z6zyMlLPGH3uUYkmPl8bGa16bQotCJZymEgW97DHenqGv9TDjg9/SXzl+ec/bmEzh/vZ12+5ZWRk\n",
1265 "5Jf8xQdU9/HncPL6a4V3TBRHceQKT8+lNiWnv2uQ4yvewv/sJznJ6b81yese20hAOMqfu0SI78lH\n",
1266 "2/kMrYbsDbFdUKI0D9e45uG18qcYbRZHx7YKdU/+DdrC6NhM9c0b+TX7E72nIuU9/Vp+f/y9Pkw2\n",
1267 "NsXyexX2Zd4r+y3dX0LP93aDMJpO95fQ/ZeEXZl8xqX/Tvj2de9fKnw8olHazW7Kv0yZJ9zZ9jQ2\n",
1268 "/SIzZ+u5m/IpU/L/ONNeVfn0firkPs+qx6Q/lk2/zIJj0tdn03/DEtly45ReK9dH2H/d9IvCP2Xr\n",
1269 "E6f61Cr1+QdKb+By/ojun6Dkc+i66ReEPdReGkYC7CPxpDBb+GXqllBqTih1i0KcmJpjSU0bktjE\n",
1270 "aZjMS+lPaqKlv1MFBbrT2envjHZO7uztXNK5snNt56bO7Z3w9IYC3XmukyvQ8rbWNEt/jYor6TWX\n",
1271 "akhJrymsqapprplSM79mec1DNRtqttbsqjlQ82oNV4Zp70Lues28TTbz1soX40a+pPAX8gmVFRLT\n",
1272 "Y6GlXy1ekUrlT82W/lbGle3Wi62kbLcWtAZbm1p7Wvtal7Wubl3fuqV1Z+v+1mOtJq5Aa1yK/gEV\n",
1273 "VDYBzWrQMb4UHuPxqx0l81FUajVXW6C3MIOotxpKQ47yKvvECZaKoDOozrWb85y5+fXNE+NVba5b\n",
1274 "moqiNcWeSFtXW8QTaLulpuXz1a2hBcXRGnd01qJZ0aqO6uKSFqZSB3yuCkdugS/fXqjOM+VoNdYO\n",
1275 "0VHYFAqErOVhT2V9udNZXNNWH5neUOAP13eZPfXl4caKoglTk+GbJ+blqATl3brxDrPv9nfCJrnP\n",
1276 "8bYTpnceUtrODqUvusUwtZ2Qcv/mG6cr/iVhiuk5Y4+oVvxLdETJb1JGShoCr95+3GOGIoVFjprU\n",
1277 "Gy1UqH49n4r4MGvC+kTeZ4000l6rIyKWvtXz1lvvihXvvsW+OXwv+2bLnvb2PVS3uXxeWEDjYz3V\n",
1278 "7R3egkfTb86mvyv8fEz6Y9n0y+PSv51Nf0/45Zj09dn03wh/pGefy+fiBfzZY8KzqaYQb5appow3\n",
1279 "fjMFSTTZArL2SBpxwNLv4yu9GCVmh95xVn5EK5P5YOQfjJlxmEy68MFo6S9h2BQqcZUESsYe2G4u\n",
1280 "2VGyr+RoCTaFSs7Dqimmsl8zpfOmjF1seKCpeXNW0yW13TGr7pdGx3FV54SGuKPHXl5V5c8zBaqq\n",
1281 "yu09jnjEH3WarhnbVaqC4rm317IXh6dHpjSUWDQaS0nDlAhLD3fW3j632K4pyM8M+4q+oUqRXGPK\n",
1282 "/P9/aF7js7Q4ndKblfFIbpsunu6g9BZl/Hp6TPod2fTfCk9m4gyzfxa/xtMn0Tzx5JeEMemvZNPn\n",
1283 "fEne0gjz8e4X7CzXvmcwdWpmKDUrlKobws67vEUo2eqIQ3CmJVU0iGOJOksqMpiKhLBw71Bj6Otw\n",
1284 "dvg7oh2TO3o7lnSs7FjbsaljeweYMDD0dZzrEImW4ebR9VoVf69VudebeRv4h4arz8D2lImT+JBn\n",
1285 "UxF1ShVvUdhM9F300fjmK/AFfU2+Hl+fb5lvtW+9b4tvp2+/75jPtFC6Sf4J1wp6aE+xx9UT6In1\n",
1286 "dPfM61nas6pnXc/mnh09+3qO9qD59JzvwZ7i+KWgFw6MmRQ+/kUaJ3ordAHZ6RMWcmMWAqqxtpeN\n",
1287 "7Bdj1wVMpRJLZjZ74hOKEvPvrC5ffctNwfYvV7TWFWtUpsyK4YuF07rqbWUBu6/RZx23fLAGbaEq\n",
1288 "bEk2t5XpjQ/FQp32qkk1Py5K2LIK30qNLeh1lTtyCqpinsza8XfsJ/TOe6mNtAl7rpv+OWWuvDp9\n",
1289 "ntIGr05fKnyH0oMj74s/Fd/n6YvltYcoUptC+mzxfT6jR1lBKhbCQCEOEfEYbe2lYhlv5AmZjfoJ\n",
1290 "meY1QXFLxmBahlESQeZ5I/M6vX5v1DvZ2+td4l3pXevd5N3uRQRoNDLvOW+GAdTDG40nQ15G40zu\n",
1291 "VaPw+CVqBYZkSZML3g7JTX8wQPPKVNB2Eh+gg9R2gq5gIBgLdgfnBZcGVwXBI7wjuC94NIi2Ezwf\n",
1292 "lKnBG9A0Gy42UNNsKGgINjQ19DT0NSxrWN2wvmFLw86G/Q3HGjD1YqxvvDZAWob17SqKSXF29Lph\n",
1293 "0o4ebY8Oe66OqSaGPx68JiL17okbNw6vvYpYLDs2XKH3u1x57/8wJv1r2fQnhb+/7v1zsu1kfPpS\n",
1294 "rEWVMeYKH2NiQlL4ZqotBK6ftsyxULsFHuZ59lJI3i5zupda+pv4HzpokGLyV2WWVHIwlQxlR5EM\n",
1295 "Md+eJtHDX2GeqhCvMEZ/sCZK4FUkLiboVSQKEsFEU6In0ZdYllidWJ/YktiZ2J84ljBd0+Vprsgc\n",
1296 "jTnK6TAo5ho/WdjkkyIHWzvayTWaCcHaZKUv2dvQOLe5dPhhVXFdi7fxZnukOuLxui1yH2+b1VPW\n",
1297 "MqFoTO/WqEWLTXlP/tZbw6XeSRPc9WXVja48TbFT6d1/1zGnsDpakhnLLaKL5PxFpf8OXDd9jnDw\n",
1298 "uulLhe+PSX83m/6+sF32YeYT/WkVYtU/ruT/93w+YtjhYad5vy4T+lPlIRBglVtSBYOpghCd3DIy\n",
1299 "yVYN4gVVYPuw38RTuapePCizDYyhrcr00HH+FeMmfxf/4JJHf/RQlbFE3qLst+K9Wi9a6b1aC6xB\n",
1300 "a5O1x9pnXWZdbV1v3WLdad1vPWY1kXkwH1zK0JnR3eR4M04HX2Ipb8/hzZIsTvuXrCt6dAo5ore0\n",
1301 "tP+LGNouu6IPv8FUM+aQI7oYaty4UdZFT3F5FIuQ0zKaU38sCpm5nAnUb+T0J5k81+q5LvqiuJ9r\n",
1302 "XlXCQ3tKVT7YmPgu0TyW4yv0VfkQSXG+b7nvId8G31bfLt8B36uYx8w+6gLmUH8+l6hPCYMgpAKh\n",
1303 "ccrsdafUMcps4NOVWdWYfdSxe5AGsT0vM02x0vz8UvwbN0Wx14drM5ORyuEoKsI/0sFHfj5iEbay\n",
1304 "1wWbMH2PUZMDHTw7BueO3T/VT5oPVYaPtmqXOqDOGLeuUq9Tb1bvUO9TH1VjtFWfV2Om1rkU5QSr\n",
1305 "OVJgnCq9TV9QkqduF12xicUF/8hEdX5JhVX0f/xabn2DP1d+P7w+XGfh/YF9jt7P54YFxXffzX5J\n",
1306 "89nXKP13C+X0efwhnKqdPP0JZR4tFn6lpM+k+5+g+y89IN/vHnEL28ak/+7SaD438f6TyWep8I2R\n",
1307 "HJ7eQf0K/XOLkv8/0v1Xp88TnpLTeT1Ps7PZ9N8JX6X0/HH38/q8mF37ieXUHp9WxvH+MemvZNPn\n",
1308 "3CB9rfAmpVOcKUo/RPm3zZDzt/P63Er1kdN/9ys5vfSq++cl5PRxsRGQz6rrp39ukbyHU87nD8QI\n",
1309 "uUW4CIV8Lqnisk4+15KaDp18Osw6atSfUa8mfzDo7l20tuhydvm7ol2Tu3q7lnSt7Frbtalre9dA\n",
1310 "15EurC26znXxqZ2WK1zpRzlZq4IxmnnuZ9PMkxi7kheTNHYlC5LBZFOyJ9mXXJZcnVyf3JLcmdyf\n",
1311 "PJbEnOT6zJr5uIAWuquCX5CS86Mb6ueN4aq6G8S7SIyPjFFuy7++gt6jsjpuEAcjcHXEDL1alN+z\n",
1312 "G+8z+55/N1dQ9O332YP0/n+o7GU9ldHDwf+rpPP7m4Qbp4/hC64Qntuj1WDjV0sewE4iZ3TSClOL\n",
1313 "5aWAQ8LsnDQu9GbuVec6e1SiWi3H+MWRAlnl8XHK4DIEDDFDt2GeYalhlWGdYbNhh2Gf4agB45Th\n",
1314 "PEip86we5aDVRY4XhYPKArNYmZa4pj+e+rdR3gLI0P/+5V+OJwCeMUOmAF7S+NBYDuC/bVwCEuAs\n",
1315 "B8n3ZA4SLscfg4Mkm/61bPqTinzHcZbQOPD0mPSL2fR/FbZm0sX8MfevFU4KModNgI3wcb5ZGFCs\n",
1316 "U2qGaMaSz2fjyhq/vxTKJdmR1OCMN1UXwkeK4pNd3Y3jHb6xwkhBfTIfMqaBXFUE+XC/l16RF1Gr\n",
1317 "Yt5u7zzvUu8q7zrvZu8O7z7vUWgOJ73nQa7YTPdfV/e7AXnN2OO6kXHz5PVJba5/QvAJVDfZzWJl\n",
1318 "3+oVkveQsh77jTDqY634YGO8VMbRcX6aGF8/f/30pcr8thh7PeIrgrx3rhOKhB8p79nC79/P09dT\n",
1319 "+leFd+g9+4XXWIBZYQsBbY4NUUjKIUGOt90KzySK5XBWhGNoJXxKA8MjjL3WLq+DAP/EyxOFXPYX\n",
1320 "e7RqDR82x3kxbcN5VyuM/VtxZcbVGbUc+AFG3FjoF4D/Y59wFJ63CE8vG7bL7BphBRZKg4CNYLfR\n",
1321 "g+pFJDrUi/BQ3s+OwUPZBb+CHL2okGgslHJyFG4HKVdFqX+Ab3AUoIXTQRm4ZFPwyHwNAKcMaRvA\n",
1322 "jC/uU9JWSGdxNQvwqDFjyEqnJFeHg8YRuOyjKIl0lf6++AMEuxwS/xOsWn8HUd4lypHU9Rg8Ml6w\n",
1323 "q+B+NR9UBb3w9V3GVuOJdoHaZYpmPuhJQGeWnqzthddvN4QC1utYuYrRkXOg/CUW2Tr8sXy2PHfG\n",
1324 "8KYr7IGPN+Ks4qDynlQPkT+VjU0FqaZAMdbNQ/15XJhfAJ/LixwGvpL3VN7uPNUKSZVngMRA+C8z\n",
1325 "JRyE31Yu4DwdZsKlC4R6IoWRBCGdmrLMGZJeUPiGFkpn4Lm7JueJLN+EGbwm2iHJJGd/0ARud0vK\n",
1326 "MpQ0g452jeUJyzbLC5aXLboVSVvcMtWywHKX5WHLVyxPWXZbDlpyFqbftFyCGXaORdnUegHMXmYH\n",
1327 "2AZmOhY57nOscTzh0Cy8Dq1/lsBEsOYqnqRW+RRRHBy4W3xE/BswE8bxjo4T/Zl8mybUr+X35BI/\n",
1328 "Nl6ZkT5RjHlm9aoq5dNF3jV0XnhesxHD71kPsw//J2sYXjt88tFb2b+z54bfZHr28PDaDThGPHJE\n",
1329 "fIU6ENhwKpIC0+wpEITc3AZBLYRGXuQYHfkRx9jInzg2jwxwjBMmCF8a2c3xrZFfcxwi/BnhGcKz\n",
1330 "QBZFPixG2ESYRG6sDTmwh+meRzhqqEQNlaihEjVUooZK1FCJGipRQyVqqEQNlaihEjVUooZK1FCJ\n",
1331 "GipRQyVqqEQNlaihErVUopZK1FKJWipRSyVqqUQtlailErVUopZK1FKJWipRSyVqqUQtlailErVU\n",
1332 "opZK1FKJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQdlaijEnVUoo5K1FGJOipRRyXqqEQ9\n",
1333 "lainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUop5K1FOJeipRTyXqqUQ9lainEvVUok1Qj7zKUUOo\n",
1334 "JdQR6gkXjqzhmCI8jhRmIDQSmggf41jCa/5djlHCGKU0jzyLU1fCBOFLhD8beYvjGcKzQEa/4rUF\n",
1335 "NhEmkQOvLb+f1/MtoZrXc4CjhlBLqCPUEy4cWcoxRXgcKbyeQCOhifAxjrVCiLeDWiFKGBMsHJtH\n",
1336 "fscxTpgg/JlQwPEM4Vkgo/tZjLCJMInf8hry+9kj/J4Qr+GLHDWEWkIdoZ5w0sjXObYSJgnbCTsJ\n",
1337 "JxNOI+wl7CO8jXAh4XLCuwjvJryH8F7CdfwdhYT1I3/k+DSlPEP4LOE2wm8T7iZMER7i0g4J/0bX\n",
1338 "rxAeITxOdT5B354kfIPwFOFpwiG682eEZwjPArnk+W+55IEmQnpG1kVIT8q6CXsIpxBOJbyZcAbh\n",
1339 "TMJZhLMJF+Dp2BK6Xkq4jHA56sPuIrybkCTDSDLszwnvI3yAvn2QcCXhKsLVhA8RPkx3PkK4hkp8\n",
1340 "jD9FlHpKlHpKlHpKlHpKlHpKlL9fYCthkrCdsJNwMuE0wtt4O4xSz4ryd4qUuwjvJryH8F7CdYTw\n",
1341 "t47yd4rrZwifJdxG+G3C3YQpyvMQ7y9R/h5RynFKP0EpJwnfIDxFeJoQo0eURo8ojR5R6uNR6uNR\n",
1342 "6uNRRk/B3yCQnoW/KeAMwpmEswhnEy5AnfmbwvVSwmWEy1Eif1PAuwkfIHyQcCXhKsLVhA8RPkK1\n",
1343 "WkN5YrSJ8Xfxa44aQi2hjlBPOIn/KsbfBTBJ2E7YSTiZcBrhbXT/Qi6rGH8XuL6L8G7CewjvJVzP\n",
1344 "+3iMvwVcP0P4LOE2wm8T7iZMUW6H6PoI4XHCE4QnCd8gPEV4GshlDjQSmgiptlzmQKozlznSZxDO\n",
1345 "JJxFOJtwAWrIZY7rpYTLCOm5GD0Xo+fiMgc+SLiScBXhasKHCNdQbo/x62Yae5tp7G2msbeZxt5m\n",
1346 "GnububS/y7GVMEnYTthJOJlwGuFthAtHHue4nK7vIryb8B7CewnX8d7XTKNZM5c5Up4hfJZwG+G3\n",
1347 "CXcT/gPVJDXyDMe9lHKE8DilnyA8SfgG4SnC04Rv8RbVTPNFM80XzTRfNDOqP5c/kJ6Cyx84g3Am\n",
1348 "4SzC2YQYnZq5/HG9lHAZ4QOU24OEKwlXEa4mfIhwDf0WM1ScpB0nacdJ2nGSdpykHSdpx0nacZJ2\n",
1349 "nKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpyk\n",
1350 "HSdpx0nacZJ2nKQdJ2nHSdpxknacpB0nacdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpB0n\n",
1351 "acdJ2nGSdpykHSdpx0nacZJ2nKQdJ2nHSdpxknacpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGkn\n",
1352 "SNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0ja\n",
1353 "CZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmSdoKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaSdI2gmS\n",
1354 "doKknSBpJ0jaCZJ2gqSdIGknSNoJknaCpJ0gaa8UMNqsFF4S8oUXhRdHhvjVS4RYgbxEK5CXhB/y\n",
1355 "e16iGfwlmsFfohn8JZrBX2L307crCP+C4yG+XgL2ES7ktTqE/QyOywnvIryb8B7Cewm/SIgZ9pDw\n",
1356 "TV6fQ8IWwqcIn6ZvnyF8lnAb4bcJdxOmqKy9uObrGWAP4RTCqYTTCG8mnEE4k3AW4WzCWwjnEM4l\n",
1357 "vJXw86gJu53wDsI7CZfQt0sJMcIfJ63hOGkNx0lrOE5aw3HSGo6T1nCctIbjpDUcJ63hOM37x2ne\n",
1358 "P07z/nHSGo6T1nCctIbjpDUcJ63hOGkNx2kufotmzLdophvi169yTHH8Gcn/ZySZM3R9hq7P0vVZ\n",
1359 "XDMDasuR15Yjry1HXluOccIEIa8tR15bjkOEPyM8Q3gWiNpyjBE2ESaRG2rL8WG6h9eWGalEI5Vo\n",
1360 "pBKNVKKRSjRSiUYq0UglGqlEI5VopBKNVKKRSjRSiUYq0UglGqlEI5VopBJNVKKJSjRRiSYq0UQl\n",
1361 "mqhEE5VoohJNVKKJSjRRiSYq0UQlmqhEE5VoohJNVKKJSjRRiZXQvzhGCbn+xZHrXxzjhAnClwi5\n",
1362 "/sXxDOFZIKNfQf/i2ESYRA7Qvzhy/Yv5KX8/5e+n/P2Uv5/y91P+fsrfT/n7KX8/5e+n/P2Uv5/y\n",
1363 "91P+fsrfT/kHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKP8A5R+g/AOUf4DyD1D+Aco/QPkHKf8g5R+k\n",
1364 "/IOUf5DyD1L+Qco/SPkHKf8g5R+k/IOUf5DyD1L+Qco/SPmHoPNxjBJyvZIj1ys5xgkThFyv5HiG\n",
1365 "8CyQ0f3QKzk2ESbxW+iVHLleycKUc5hyDlPOYco5TDmHKecw5RymnMOUc5hyDlPOYco5TDmHKecw\n",
1366 "5VxPOddTzvWUcz3lXE8511PO9ZRzPeVcTznXU871lHM95VxPOddTzvWUM3SlFxl0JaCWUEeoJ+S6\n",
1367 "MIOuBEwSthN2Ek4mnEbYS9hHeBvhQsLlhHcR3k14D+G9hFwX5shnWAa9CSnPED5LuI3w24S7CVOE\n",
1368 "XBfm+G90/cr/7e1MgOwo7jPerZV2Vxe3AWMsP+MDDEKWhGBmxGGt7gvd4pAlpKe3o92Zefve8o6V\n",
1369 "VoBlrxHIB5CkcscCh5CkApWEHChEoOC4HBIUJakk5iocQ27HSZzEOSqpOFH+329mtU+ywJWqVLx+\n",
1370 "3+s309PT/f96ju7+PgG+CB6nzi+z9xXwVfA18HXwa+T8Ovgm+JZQY2GvkZRwJkgbNRb2GkkJV4Ar\n",
1371 "wVXgavBWcB24HtwAbgS3qXUaC3uNsISDYKL6aCzsNcISEhlPZPQkNayDLfa2wRFwL7gPHAX3k/Me\n",
1372 "8ABntLGwD+A3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8A\n",
1373 "fgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4\n",
1374 "DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3gN8AfgP4DeA3\n",
1375 "gN8AfgP4DeA3gN8AfgP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8Q\n",
1376 "fkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4\n",
1377 "DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4DeE3\n",
1378 "hN8QfkP4DeE3hN8QfkP4DeE3hN8QfkP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8IfiP4jeA3gt8I\n",
1379 "fiP4jeA3gt8IfiP4jeA3gl9G9z6C3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC\n",
1380 "3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4DeC3wh+I/iN4JfZAB/BbwS/EfxG8BvB\n",
1381 "bwS/EfxG8BvBbwS/EfxG8BvBbwS/EfxG8BvBbwS/zCH4CH4XaX7McArYDfaAveAt9saySPNjhovA\n",
1382 "xeBScDm4BtxOfnvbN0xIp2AGVsEh8JA99xdp3GR4GHwUfAx8HHwSfJrSvkT6RfA4+DL4Cvgq+Br4\n",
1383 "ulDzY4YzwJkgtdX8mCF11jjLcB24HtwAbgS3qYYaPRkOgIMg7fK0y9MuzY8ZtsERcC+4DxwFD1Da\n",
1384 "mKX7NIdgOAXsBnvAXvAWY6pPcwiGi8DF4FJwObgG3A7uOHnQMCGdghlYBYfAB43xPq6gPs0hGB4G\n",
1385 "HwUfAx8HnwSfoiZPnzxs+AxbXgSPs/1l8BXwVfA18HXwDXvX7dMcguEMcCZI/TWHYEgrNIdguA5c\n",
1386 "D24AN4K6Ivo0h2A4AA6CLUprgyPgXnAfOAoe4NgxS69xa12/YQscccsND5I+5LYZPgQ+zJZHwCPg\n",
1387 "s26+4VF3k+Fz4PPkPAa+AJ5wG/waf5vyW2+xLX4H6bvAneAusAwOk/9usAEesKN2Wg03GLbsLDut\n",
1388 "hlcZHmTLIfAh8GHwEfAIOZ91FxketXrutBoKn2f7MfAF8ISb5XdaDe0oq6FwB3gXuBPcBZbBYfLf\n",
1389 "DTbAA7Y90ZyJ4R2gjc0Nd5FOwBTMwCo4BN4HPmj9IdGcieGPgj8OfoG9h8FHwcfAx8Enwac51zNK\n",
1390 "a87EcCW4ClwNrgHXgreC68D14AZwI7gJ3AxuAbeCu1UfzZwY9oMxuIe9A6Cu/ZQ4pMQhJQ4pcUiJ\n",
1391 "Q0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxSIlDShxS4pASh5Q4pMQhJQ4pcUiJ\n",
1392 "Q0ocUuKQEoeUOKTEISUOKXFIiUNKHFLikBKHlDikxCElDilxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\n",
1393 "Q0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHjDhkxCEjDhlxyIhDRhwy4pARh4w4ZMQhIw4ZcciI\n",
1394 "Q0YcMuKQEYeMOGTEISMOGXHIiENGHDLikBGHYbtyZxm2wIPgIfAh8GHwEfCI0K5E4TZwB3gXuBPc\n",
1395 "BZbBA4b7NVdm+LThPcT5HiIwxnzRGPNFY8wXjTFfNMZ80RjzRWPMF40xXzTGfNEY80VjzBeNMV80\n",
1396 "xnzRGPNFY8wXjTFfNMZ80RjzRWPM4Dl3ib8s/68qGU7PNSVos3rsV57uciV3QZGe3JFniuWZX6S7\n",
1397 "bXtUpKUnXFqkLyB/l/OTp9r3Z/XfWCHt3cXGRp6e5M7x+4p0l1vkHyjSkzvyTLE8Lxbpbtv+1SLd\n",
1398 "46/y3yzSve6yrguK9FQ3q2t2kZ7W/Uddq4v0dDdn2uVFeoZbPW18+3luxrQfLNLnu95pX+wbiWtJ\n",
1399 "o7S4Xs82xQPtarnRseXGUjhnbv918bwbS/Pnzpt/7dwF9v9iU57tWmUrjkiapXKp1Sj3x0PlRlaq\n",
1400 "7ymtjJP+uLo7bgzEjdLSRruSDZWblcGkFtdKfStml+J9lWq7mYzE1dFSNanEtWbcX2oNNurtgcHS\n",
1401 "2qRWb40Ox6UVQ7tXzi6Va/2lofJoaXdcasQDSbMVNyxzUitV4karbN9pu5E0+5NKK6nXmnPcEld3\n",
1402 "w27UNVziBtyg9fGfM37nu7lOs0ol6/mJq1meluUZdrFtWeGG3G630s229F7+5rjqGbnmuIr9GrLv\n",
1403 "krM3FPsrdZyhya/YvmP7HjHst5x9pGqWq2H7F9vxdZe5TbZtwLWthLJtP3ueGy0dWglzrZzrbP88\n",
1404 "tqgN8wyvte8FBZ6eq7O0a0+Vdvo5Empbtk/Lftvz3fYNUZfMttXdHsOVti1hT9UiozYNgCXr9w2r\n",
1405 "e8Xy6pimpQaJlMpXZFYQxdjtsz1Vy9m0vSOUM2rbFdUKeZvESHUYtBLrllOR/F7slG2fjtK5Vd5u\n",
1406 "cjSIqNrVopZ5yQk1qrClZfnz36mdqUHefurSMqxTnznvcO4+y62jypSxnBi0YD+Gw3faWyKOTX7X\n",
1407 "irqdyYiOm2f3l9D+8nbuKdpSsrrEsNM8xc6g/R7hqIEiJnkZ461XHMZLbbK/SSqmlnuIet7CPba3\n",
1408 "whHq16s44szydKbYrgldGwl8fTdLs6lVXJwvoY357z1w3zpVbt3iWSUW5VOxV33qZ8Qp76HVom+V\n",
1409 "icREW5LiqPwc4/046Sgxj9Qy27O7OHq87yyHnTbHzKYPtalfXoeynbNJSn0so/w2sRsvc/ys6uPD\n",
1410 "RUzFZYWt42dpEptq0SvV0/L25deC7lBDHNXq4HWiPXuLfSo5j3il2KJ6j8LWliL3Xju6cZZeNUTc\n",
1411 "8nhdaeWPtzq2X+MRXM7vGlfxRN0HC/abRZ3KRXzGa3d631Ht98JcicgNdcQqKUqZ6E3DnLF1FvY7\n",
1412 "eZnDvTDnpW15FMecizPZO9u9Le+ZJTtX3t783qOrMa9dC84q3FMTcg5yLytRVqPgq8w9vknuOmc/\n",
1413 "PR5lys63JNwR8+s1z9HZPwdhKHH7aW+r6GPj97OSu8K2X3Fa2ae3o0xbVLqupgrbKrRY99j4tDtj\n",
1414 "szhbi6jkd5v8Ph2TI+ZOMtF/8p5ds0iViz6cPx2Sjntotbi/7rZPlYiNdpxxoLjDn8lFuYhrw2Je\n",
1415 "Z2udK6mzrvmTIOGekF89w7S0DL/j19QeWqQrtV5cDS2uvtZppQ1yXP+pe0bnPS1/+i+gju98rx4v\n",
1416 "7czeXuL+0ijin9cn7+Nv/9TQ2TKOUizWcO/Tc6sMS4nLn1z59Zt1PA/PFsu8VhWOKNP+t8+9rojO\n",
1417 "ROTG823graNFjdtWyxJvS1WiP/EsnMM7Tctas9Bpve97vRP973J/lFrpOjj9uah+2dmO8beXQp/v\n",
1418 "3Mln3Hx3lv/5++0zyXJ1ud+2CP+8necX3Ifch638K91VVt7vuOPud93fuI+4q901drWccL/nft/9\n",
1419 "gb0hzbHa/BlvVXusbP0jwn9otflj9/3uF+2NaoG73t3g/sLeGv/enstfdS9bS1+xp/RCu3Pc5P7W\n",
1420 "Pedudn9lb0S6Nz1k7f2ivV1Mtdr3WYxnug9YW5e5j7md7i63y93iFrk33Dfcg9bn/tTa9XV3v40V\n",
1421 "3uvOdZ9zx6zHjLkvu0/buOtZqavdq9Z7honI3e497in3K+6Xjatv2ojhp6xHf8ld6n7T/Yy7xD3v\n",
1422 "VrvPGIfvt3fcJ91vuBesl71p7/prLbojxkLb3Wq9Yb17n3vC/bnb4LvcP7gfcf/oNrrLrYd027vo\n",
1423 "qLvH3et+yb1ld6eL3L+4f3X/5A67R91PuvvcZhsTTrdRRK873092L7pzbOy7xe5Uj9to5bfcr7pn\n",
1424 "bGz4a+4rbprbaiOfP3G3ub90D7hZ7jL3bhsXvWTjytvdt9zF7t/cP7vX3efdu9y33R3uE+6T7lPu\n",
1425 "gPF7p9vmPu62u79zR90Pux3ur92Fforv9j2+10/10/x0P8PP9Of4c/15/nx/gb/QX+Tf5S92j/lL\n",
1426 "/KXuJ/y7bWT3AzYS/4L7afdjNhb/df8eG7P+rI3Ofshf7t/rZ/n3+ZL7L/9+d9Jf4T/gP+g/5D/s\n",
1427 "r7QR1Uf81e7f/TV+tr/Wz/Ef9XP9PD/fX+cX+Ov9DT7woY/8Qn+jv8nf7G/xH/OLfJ9f7Je4//RL\n",
1428 "/TK/3K/wK/0qv9qv8Wv9rX6dX+83+I1+k9/st/it7r/9bd752/0d/k6/zX/cb/c7/F02Uv4Pv8uX\n",
1429 "/W5f8f0+9nv8gB/0iU9tTF71Q77m6zZ6vts3fNO3fNuP+L1+nx913/H7/T3+Xn+f/4Q/4D/pP2Uj\n",
1430 "20/7+/1B/4B/0B/yn/Gf9Z/zn3cfdN83ZU6tXa12D5UrjXrtnOG4kdT7bXDFiGnysnajPnWgUR6J\n",
1431 "51TKw1PLlXaL1DmVpFFpD+2pxvvYUSnbwR2pcrU1tZVU+8k8oz+xwppJUz+m5SdSsqddS+bOXxJN\n",
1432 "3d2I8xP0NpLagBLnDbZrA+VGe6habre0YWZ/vVWuqF76Nb1SHxoq57/P7UjrvFOWxtVWmbKvixbk\n",
1433 "331R/r14ydTyniS5Yd78MJoaN1vJULkV92vf8nD5cn3Pnz/v+uI76unL69rdRwV7+uoD9VqcTV8y\n",
1434 "0fhpS07Vq3spTbevRr3c6l7Gr55lRRHLKGLaslPZe5YVpa3oKG3Fqd0zVnQ0a/rKiTyTV+4uN7pX\n",
1435 "EdyeVXnp01ZNFLuqKHb1xCEz1nSU1b0WErvXUr8Zazt2TV5rxXSvy/evy/ev69jfs75ozHoaM3N9\n",
1436 "J0ndm/LjNuXHbeo85WZ2Td/cUaXNnfu35Mds6TwXfWNe3+Qtau7WvLlbi/Nv5fxTtqq3zNzaWYue\n",
1437 "rUXzb5841/Q7J9Ld26jKtG0TASsXhZZzkstFAZUOWioTJPfnJPfnJMc5yXFRRJyTHE8UHhelDXSU\n",
1438 "NjBB8kAnyYMdJA+q1Une6iQvvSfJy+q1w6txs5lOTzvimXXGs5pTUc3DWu2kuCqKa/n+Wr6/1lmJ\n",
1439 "Wnm43mw16sODcU+9aFY9p7t+Gt0NypjR6DxvIw9OM6e72VG9Zme2Vn7e1nfTvXhySw1v5w1vF+dv\n",
1440 "53S3obt9Gt3tIr57O+ge7aB7f073/lMhn7Rq9aQk5XRz+5YW33NPzd65cQeZPZ9m2VPfL12+dos9\n",
1441 "y/gXrk+eZI/P4kbNtuX5vO2bxHevfWrknN97YvzPvdK10Pd23dt11C+c/J0p39bfpKWT1k3aMmms\n",
1442 "90TX3N5ne7/MH7m7FhZ/9/J3NP/Tcd3f6Lmt5yv66x3hmBP61/jsbFPsidxj577Q3guuxsFzg717\n",
1443 "5O8bI/asP2ZP/uP2FvE1e3t4071VPB/Hn2n5U2z86aUn1hq/s3i+DPMMGbNnubwdcnbI1yFXhzwd\n",
1444 "cmjIUXH85EtyRMgPITcEDoQZ6IalGpZmWIph6YXlQpIHSatqWi/TapnWyqR9XXzWc8g1Is+IHCPy\n",
1445 "i8hnIX+FnCLbKfEAHhE5ROQPkTtE3hDpVuULkStEnhA5QuQHkRtEXhDVWz4QuUDkAZEDRP4PuT/k\n",
1446 "/ZDzQ/pPqT9RU3a0z+ogp4d8HnJ5yOMhh4f8HXJ3yNshZ4d8HXJ1yNMhR4f8HHJzyMshJ4d8HHJx\n",
1447 "yMOBRvGAHafYTUIFfIy5ZWmAp6MBlgJY+t8TllMr4loP12q41sKHbdvd9pHe9xr0vlL7SlMqpa90\n",
1448 "vlL5SuMrha/0vVL3KkZS9krXK1WvNL1S9ErPKzWvtLxS8kqhqhUIrT9o9UFrD1p50LqD1hu02qC1\n",
1449 "Bq00aJ1BqwxaY9AKg9YXtLqgtQWtLGhdQasKWlOQNncSSlnpZM/DISenm9xx8sbJGSdfnFxx8sTJ\n",
1450 "ESe9odSG0hpKaSidoVSG8sCdi3dNTjT51uRak2dNjjX51eRWewvtXTfaPCnzpMuTKk/+tA340+RO\n",
1451 "kzdNzjT50uRKkydNjjT50eTUkkNLTjT50ORCkwdNDjT5z+Q+k/dM6mxps+U6k5JdjjP5zeQ2k9dM\n",
1452 "TjP5zOQyk8dsnF25y+Qtk7NMvjK5yuQpk6NMfjK5yeQlkzpD2gwpM6TLkCpDmgwpMqTHkBpDWgwp\n",
1453 "MaTDkApDGgwpMKS/0FqztBdSXkh3odV0raVrJf3M3iWdhVQW0lhIYSF9hdQV0lZIWaG1ZznAbsZ1\n",
1454 "JM+RHEfyG8ltJK+RnEbyGcllJNeO3DryF22nlx45aw+Vn+jte+QR/ENyD8k7JOeQfENyDckz9DpX\n",
1455 "7LdQQ0gLISWEdBBSQZytx0r50NErUTywpmcfaR2kdJDOQSoHaRxGuVovxf1z81nvdPJFyBUhT4Qc\n",
1456 "EfITyEcgL4ScEPJByAUhD4QcEPI/yP0g70PeX57A9SDPgxwP8jvI7fAUV8thfA5yOcjjIIeD/A1y\n",
1457 "N8jbIGfDG9yTJ+6w0iJIiSAdglQI0iBIgSD9gdQHeX94At2BVAfSHEhxIL2B1AbSGkhpkHN9xEaX\n",
1458 "a22crLH4iI1MD9r3IRuVPWSfhy39iH2O2OdZez4dtTHvc/Z53vYds88L9pGOQCoCaQikIJB+QOoB\n",
1459 "aQekHJBuQKoBaQYOWH6dbYP0AlILSCsgpYB0AlIJSCMghYD0AVIHSBsgZYB0AVIFoAmQIkB6AKkB\n",
1460 "0ALYRzoAqQCkAZACQOv/B6ys2f+vd9C1/wd3UY3cZ2lVVmuyWpHVeqxWY7UWy0qs1mG1Cqs1WK3A\n",
1461 "av1Vq69l2jyL+/BLeBQm0WrV+EJ8E3JNyDMhx4T8EnJLyCshp4R8Ep1PSa2uam1VK6taV9WqqtZU\n",
1462 "8xXV/J1Kf+5/AIGHtqIKZW5kc3RyZWFtCmVuZG9iagoyMCAwIG9iago3MDc0OQplbmRvYmoKMTkg\n",
1463 "MCBvYmoKMTI3MzQwCmVuZG9iagoxNSAwIG9iago8PCAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTGVu\n",
1464 "Z3RoIDY3ID4+CnN0cmVhbQp4nO3NMQ0AIQAEwVNMTYKOV4AZKhosIOQxQUNmuq02uWynZ2WmpWac\n",
1465 "LreHAAAAAAAAAAAAAAAAAAAAAPCY7weB+gXnCmVuZHN0cmVhbQplbmRvYmoKMTggMCBvYmoKPDwg\n",
1466 "L0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAyNjEgPj4Kc3RyZWFtCnicXVE9b8MgEN35FTem\n",
1467 "Q0Rst5UHC6lKFw9Jq7qdogw2HBZSDQjjwf++fCRu1ZPg6T7ece+gx/a11coDfXeGd+hBKi0czmZx\n",
1468 "HGHAUWlSlCAU9zcv3XzqLaGB3K2zx6nV0pCmAfoRkrN3K+xehBnwgQAAfXMCndIj7L6OXQ51i7Xf\n",
1469 "OKH2cCCMgUAZ2p16e+4nBJrI+1aEvPLrPtB+Kz5Xi1Amv8gjcSNwtj1H1+sRSXMIxqCRwRhBLf7l\n",
1470 "q8wa5FZexfIAzwwuf9wiQ5mhyvCY4enOuKYGdXbrW4M6hsuyiNQMl4zXOM/95Tha3OOmmy/OBclp\n",
1471 "2UlrVKk0bv9hjY2seH4AHtCFLgplbmRzdHJlYW0KZW5kb2JqCjEzIDAgb2JqCjw8IC9DSURUb0dJ\n",
1472 "RE1hcCAxNSAwIFIgL0ZvbnREZXNjcmlwdG9yIDEyIDAgUiAvQmFzZUZvbnQgL0F2ZW5pci1Cb29r\n",
1473 "Ci9DSURTeXN0ZW1JbmZvIDw8IC9PcmRlcmluZyAoSWRlbnRpdHkpIC9TdXBwbGVtZW50IDAgL1Jl\n",
1474 "Z2lzdHJ5IChBZG9iZSkgPj4KL1N1YnR5cGUgL0NJREZvbnRUeXBlMiAvVyAxNyAwIFIgL1R5cGUg\n",
1475 "L0ZvbnQgPj4KZW5kb2JqCjE0IDAgb2JqCjw8IC9FbmNvZGluZyAvSWRlbnRpdHktSCAvQmFzZUZv\n",
1476 "bnQgL0F2ZW5pci1Cb29rCi9EZXNjZW5kYW50Rm9udHMgWyAxMyAwIFIgXSAvU3VidHlwZSAvVHlw\n",
1477 "ZTAgL1RvVW5pY29kZSAxOCAwIFIgL1R5cGUgL0ZvbnQKPj4KZW5kb2JqCjEyIDAgb2JqCjw8IC9E\n",
1478 "ZXNjZW50IC0zNjYgL0ZvbnRCQm94IFsgLTE2NyAtMjg4IDEwMDAgOTQwIF0gL1N0ZW1WIDAgL0Zs\n",
1479 "YWdzIDMyCi9YSGVpZ2h0IDAgL1R5cGUgL0ZvbnREZXNjcmlwdG9yIC9Gb250RmlsZTIgMTYgMCBS\n",
1480 "IC9Gb250TmFtZSAvQXZlbmlyLUJvb2sKL01heFdpZHRoIDY4MiAvQ2FwSGVpZ2h0IDAgL0l0YWxp\n",
1481 "Y0FuZ2xlIDAgL0FzY2VudCAxMDAwID4+CmVuZG9iagoxNyAwIG9iagpbIDQ4ClsgNTY5LjMzMzMz\n",
1482 "MzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMKNTY5LjMz\n",
1483 "MzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgNTY5LjMzMzMzMzMzMzMgXQo1NiBbIDU2OS4zMzMzMzMz\n",
1484 "MzMzIF0gODcyMiBbIDY4MiBdIF0KZW5kb2JqCjMgMCBvYmoKPDwgL0YxIDE0IDAgUiA+PgplbmRv\n",
1485 "YmoKNCAwIG9iago8PCAvQTEgPDwgL0NBIDAgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMCA+PgovQTIg\n",
1486 "PDwgL0NBIDEgL1R5cGUgL0V4dEdTdGF0ZSAvY2EgMSA+PiA+PgplbmRvYmoKNSAwIG9iago8PCA+\n",
1487 "PgplbmRvYmoKNiAwIG9iago8PCA+PgplbmRvYmoKNyAwIG9iago8PCA+PgplbmRvYmoKMiAwIG9i\n",
1488 "ago8PCAvQ291bnQgMSAvS2lkcyBbIDEwIDAgUiBdIC9UeXBlIC9QYWdlcyA+PgplbmRvYmoKMjEg\n",
1489 "MCBvYmoKPDwgL0NyZWF0aW9uRGF0ZSAoRDoyMDE0MDIyMDE3NTMyNS0wNycwMCcpCi9Qcm9kdWNl\n",
1490 "ciAobWF0cGxvdGxpYiBwZGYgYmFja2VuZCkKL0NyZWF0b3IgKG1hdHBsb3RsaWIgMS4xLjEsIGh0\n",
1491 "dHA6Ly9tYXRwbG90bGliLnNmLm5ldCkgPj4KZW5kb2JqCnhyZWYKMCAyMgowMDAwMDAwMDAwIDY1\n",
1492 "NTM1IGYgCjAwMDAwMDAwMTYgMDAwMDAgbiAKMDAwMDA3MzYzOCAwMDAwMCBuIAowMDAwMDczNDQ0\n",
1493 "IDAwMDAwIG4gCjAwMDAwNzM0NzYgMDAwMDAgbiAKMDAwMDA3MzU3NSAwMDAwMCBuIAowMDAwMDcz\n",
1494 "NTk2IDAwMDAwIG4gCjAwMDAwNzM2MTcgMDAwMDAgbiAKMDAwMDAwMDA2NSAwMDAwMCBuIAowMDAw\n",
1495 "MDAwMzg4IDAwMDAwIG4gCjAwMDAwMDAyMDggMDAwMDAgbiAKMDAwMDAwMTMzMyAwMDAwMCBuIAow\n",
1496 "MDAwMDczMDYwIDAwMDAwIG4gCjAwMDAwNzI3MTIgMDAwMDAgbiAKMDAwMDA3MjkxOSAwMDAwMCBu\n",
1497 "IAowMDAwMDcyMjM5IDAwMDAwIG4gCjAwMDAwMDEzNTMgMDAwMDAgbiAKMDAwMDA3MzI3NyAwMDAw\n",
1498 "MCBuIAowMDAwMDcyMzc4IDAwMDAwIG4gCjAwMDAwNzIyMTYgMDAwMDAgbiAKMDAwMDA3MjE5NCAw\n",
1499 "MDAwMCBuIAowMDAwMDczNjk4IDAwMDAwIG4gCnRyYWlsZXIKPDwgL0luZm8gMjEgMCBSIC9Sb290\n",
1500 "IDEgMCBSIC9TaXplIDIyID4+CnN0YXJ0eHJlZgo3Mzg0OQolJUVPRgo=\n"
1501 ],
1502 "image/png": [
1503 "iVBORw0KGgoAAAANSUhEUgAAAJgAAABWCAYAAAAzIF/lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
1504 "AAALEgAACxIB0t1+/AAACutJREFUeJzt3X1QE2ceB/BfNuHFsCExQDFECjqAhRa1DGOtAvbUuU4t\n",
1505 "teDUcQbbcDiTq1d7nSLT8bBjcuBh5WxBGRDB8eWOl/MG5uwInt6LN+Xl5uxdC7aQVAJnLeYAiRJI\n",
1506 "NrxE2L0/2vRiJkE27FJz/D4zzJjdfXYfnO/sbvbHs4+AYRhAiC/ED90B9P8NA4Z4hQFDvMKAIV5h\n",
1507 "wBCvMGCIV6LZVtpsNllZWVl9fHx8S0ZGRrHRaEyoqqqqJghiRqlU3lSr1XsFAgFTU1NzrLe3dz3D\n",
1508 "MIRKpdofGxv76UL9AujxNmvA6uvrjz777LOXJycnSQCAmpqaD/Py8l6TyWRDTU1NeW1tba8HBwcP\n",
1509 "EwRBFxYWpo6Pj0uLi4svFRQUbFqY7qPH3awBU6vVe/V6/SaDwbDebrcv8ff3H5fJZEMAAGlpaTV1\n",
1510 "dXXFUqn0bmpqai0AgFgsHouMjNSZTKaosLCwb1z3d+3aNXyq6+O2bNkiYLP9rAFzRlHUUpIkRxyf\n",
1511 "JRLJPYqi5EKh8AFJkvddl7sLGABAUlISm/49pKmpCV555RVs/wO17+joYN1mzgEjSdJMUZTc8dli\n",
1512 "sYSRJDlCkuSI1WoNlcvlAwAAVqs1VCKR3Pe8J3aGrFMwNf3tiS905dPwjXnyofViPwLCSH+uDoc4\n",
1513 "NueA+fv7T9jt9iVms1mxdOnSwdbW1jcSExP/KpVKh9vb23dHRUV9abPZZEajMSE0NLSfqw623x6F\n",
1514 "6k8HnJaMPbS+8McrMWCPsTkFTCAQMAAAKpUqr6SkpIEgiJnly5d/tX379g8BALq6urZqNJo2hmGI\n",
1515 "7Ozsd/nsMPItjwxYQkJCS0JCQgsAgFKpvHn48OEU12127959gI/OId+3qB60xsXFYfsFtqgCtmrV\n",
1516 "Kmy/wBZVwNDCm/O3SAe73R5YUVHxG4vFEkbTtHDHjh1FISEhRnclJD46jHwL64ANDw+vJEnSnJub\n",
1517 "u+vu3bsrGxsbtRaLJcy1hJSWllbDR4eRb2F9iVy+fLnebrcvyc3N/Uqr1ba++uqrR11LSN3d3Zu5\n",
1518 "7yryRazPYDdv3twYEBBgKy0tjTcajQnnzp0rCw8Pv+VYL5FI7js/8UeLG+szWE9Pz8b169c3AHx7\n",
1519 "NgMAsFqtIY71Fosl1LlmiRY31gFTKpU39Xr9CwAAZrNZQRDEzIMHDwLNZrMCAMBRQuK4n8hHsb5E\n",
1520 "JicnX+rq6tqq1WpbCIKgc3Jy3hEKhQ/clZAQYh0wAICcnJx3XJe5KyEhhA9aEa8wYIhXGDDEK6/u\n",
1521 "wQAAPv/88/TBwcG49PT0Ek+jjbjsKPJNXp3BJicnSYPB8Hx6enoJwP9GGxUUFGxSKBSGtra217nt\n",
1522 "JvJVXgXswoULv7p9+/bajz76qPHOnTtPY6kIecL6Ejk4OBhL07QwPz//5dHR0WUnTpz4nUKhMDjW\n",
1523 "Y6kIOWN9Buvs7Hxp3bp1fwAAkMlkQxKJ5B6WipAnrAMmkUju63S6zQAAExMTktHR0WVYKkKesL5E\n",
1524 "bty48cLp06crtVptKwBAVlZWvkQiuYelIuQO64ARBDHz5ptv/tR1OZaKkDv4oBXxCgOGeIUBQ7zy\n",
1525 "ulRkMpmitFpt6/79+3cGBgZSWCpC7nh1BqNpmvj444/zU1JS6hmGEWCpCHniVcCam5vztm7dWuXn\n",
1526 "5zfJMAyBpSLkCeuA9fX1rWMYRrBixYpOgG/PZi4vpsNSEfoe63uw7u7uzT09PRsMBsPzAwMDT3V0\n",
1527 "dLzs/D4wLBUhZ6wDlpGRcdTx74aGBu3atWuvNjY2alxfTMdtN5Gv8vpbpDNPL6ZDaF4B27lzZ4Hj\n",
1528 "31gqQu7gg1bEKwwY4hUGDPGK9T0YTdPEmTNnKoxG49M0TRO7du06JJPJ7mKpCLnDOmD9/f2rFQqF\n",
1529 "Qa1W/2x8fFxaUlLSIBQKp/EFdMgd1pfI6OjoG+np6aUAAFNTU+KgoKDRgIAAG5aKkDte34NRFCWv\n",
1530 "qqo6vW3btuNBQUFmx3IsFSFnXgVsbGzsifLy8t9mZ2fnrlixotNlDiMsFaHvsQ7YyMhIxMmTJ8/v\n",
1531 "2bPnbYVC0es8hxEAjipCD2N9k9/c3JxnMpmiKisrzwEAkCQ5gqUi5AnrgKlUqjyVSpXnuhxLRcid\n",
1532 "RfWgtaenB9svsEUVMIPB8OiNsD2nFlXA0MLj5O/BAABqamqO9fb2rmcYhlCpVPtjY2M/5WrfyHdx\n",
1533 "cga7cePGiwRB0IWFhan5+fnbamtrf83FfpHv4+QMptPpfpSamloLACAWi8ciIyN1JpMpKiws7Bsu\n",
1534 "9j+bQBEBXwxaPa5/IsgfFMEBfHfjsTBomYJhm93j+rDohZ8vkpOAURQlJ0nyvuOzRCK5R1GU3F3A\n",
1535 "Ojo6WO17JQAcTfK8nh7qnbX94Hc/AABKpZL18Z35ent/YP//P1+cBIwkyRGr1Roql8sHAACsVmuo\n",
1536 "RCK577rdli1bBFwcD/kOTu7BEhMTr7W3t+8GALDZbDKj0ZjgPJQNLV4ChuHm7wLr6uqKe3p6NjAM\n",
1537 "Q2RnZ78bExPzL052jHwaZwFDyB180Ip4hQFDvOLsSf5c6PX6tOPHj//+2LFja6RS6TAAwOXLl9+9\n",
1538 "fv36TpqmiczMzA+Sk5MvuWvrTaXAZrPJysrK6uPj41syMjKK2U55M98BLjMzM6JTp06dGRoaivH3\n",
1539 "9x//bhpEAZs+zOc9bDk5OSPR0dFfAACsWbPmanJychPbwTnznjKIYZgF+TGZTJEVFRXnTpw4UWc2\n",
1540 "m8MZhgGj0fhUaWnpBYZhYHp6WqTRaFqnpqYCXdt2dna+WFtbW8wwDNhsNqlGo2mZyzGrq6tPXbly\n",
1541 "Zd/FixcPMAwDR44c+aPZbF7GMAxcunQpr6Wl5Y3Z2n/99ddrm5qach3HPXz48J/Z7MNms0l1Ot0m\n",
1542 "x+9fVlZWw6b9zMwMUV1dfaquru4Dg8HwHNv+FxUVXXH+zLb9xMQEWV9fX+Rte4ZhFu4SGRoaeuet\n",
1543 "t97KEYlEdkfqdTrdCykpKXUAAEKhcDopKam5r6/vOde2nioFjzqmWq3e++STT3YDANjt9iVs32M2\n",
1544 "3wEuYrF4LCEhoQUAwGQyRUul0mE27ef7Hrb+/v5ErVbbWlhYeM1kMkWxbc/FlEGcXyIHBgZWnT9/\n",
1545 "/rjzMqlUenffvn0/cd2Woih5VFTUl47PjgqAu+3mWinwhKKopd6+x8wxwCUzM/PIJ5988v3vMdd9\n",
1546 "FBUV/WloaCimoKAgtaGh4Zdzae/8HrbPPvtsuzfvYSsvL18pEonsfX19606ePHmezZQ/XE0ZxHnA\n",
1547 "IiIieg4ePPjSXLZ1VAAcny0WS9iyZcv6PG33qErBI45l9mZwytjY2BOVlZVns7Ozc0NCQozNzc37\n",
1548 "2e7j/ffff3FgYCDu7Nmz5QKBgJ5Ley7ewyYSiewAADExMf8UiUR2NlP+cDVl0A/yLZJhGAEAwDPP\n",
1549 "PPO39vb2LACA6elpv87Ozm3ubt65qBR4MzhlvgNcDAbD83q9Pg0AIDg4+N7U1JR4rtPuZGRkHD1w\n",
1550 "4MD29957L3PDhg0X9uzZ83M2x+7t7X3u+vXrrwEA3Lp1K0kul/+HzZQ/XE0ZtKDfIh0c92ARERGG\n",
1551 "uLi4fxw6dOjvNE0TO3bsKPLz85ty3X716tV/6erq2qrRaNoclQJvjsd2cMp8B7iEh4f/u7Ky8ux3\n",
1552 "l0VBVlbWL8Ri8Zi3A2TYHFupVH518eLFg1evXn2bJMkRtVq9l6Io+VzbczVlED7JR7zCB62IVxgw\n",
1553 "xCsMGOIVBgzxCgOGeIUBQ7z6LzWkj3n7AHKHAAAAAElFTkSuQmCC\n"
1554 ],
1555 "text/plain": [
1556 "<matplotlib.figure.Figure at 0x10b0ecf10>"
1557 ]
1558 },
211 "metadata": {},
1559 "metadata": {},
212 "source": [
1560 "output_type": "display_data"
213 "```python\n",
214 "def foo(bar=1):\n",
215 " \"\"\"docstring\"\"\"\n",
216 " raise Exception(\"message\")\n",
217 "```"
218 ]
219 }
1561 }
220 ],
1562 ],
221 "metadata": {}
1563 "source": [
1564 "plt.hist(evs.real)"
1565 ]
1566 },
1567 {
1568 "cell_type": "markdown",
1569 "metadata": {},
1570 "source": [
1571 "```python\n",
1572 "def foo(bar=1):\n",
1573 " \"\"\"docstring\"\"\"\n",
1574 " raise Exception(\"message\")\n",
1575 "```"
1576 ]
222 }
1577 }
223 ]
1578 ],
1579 "metadata": {
1580 "signature": "sha256:9fffd84e69e3d9b8aee7b4cde2099ca5d4158a45391698b191f94fabaf394b41"
1581 },
1582 "nbformat": 4,
1583 "nbformat_minor": 0
224 } No newline at end of file
1584 }
@@ -1,31 +1,19 b''
1 """Global configuration class."""
1 """Global configuration class."""
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2013, the IPython Development Team.
4 #
5 # Distributed under the terms of the Modified BSD License.
6 #
7 # The full license is in the file COPYING.txt, distributed with this software.
8 #-----------------------------------------------------------------------------
9
2
10 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
11 # Imports
4 # Distributed under the terms of the Modified BSD License.
12 #-----------------------------------------------------------------------------
13
5
14 from IPython.utils.traitlets import List
6 from IPython.utils.traitlets import List
15 from IPython.config.configurable import LoggingConfigurable
7 from IPython.config.configurable import LoggingConfigurable
16 from IPython.utils.traitlets import Unicode
8 from IPython.utils.traitlets import Unicode
17
9
18 #-----------------------------------------------------------------------------
19 # Classes and functions
20 #-----------------------------------------------------------------------------
21
22 class NbConvertBase(LoggingConfigurable):
10 class NbConvertBase(LoggingConfigurable):
23 """Global configurable class for shared config
11 """Global configurable class for shared config
24
12
25 Useful for display data priority that might be use by many transformers
13 Useful for display data priority that might be use by many transformers
26 """
14 """
27
15
28 display_data_priority = List(['html', 'application/pdf', 'svg', 'latex', 'png', 'jpg', 'jpeg' , 'text'],
16 display_data_priority = List(['text/html', 'application/pdf', 'image/svg+xml', 'text/latex', 'image/png', 'image/jpeg', 'text/plain'],
29 config=True,
17 config=True,
30 help= """
18 help= """
31 An ordered list of preferred output type, the first
19 An ordered list of preferred output type, the first
@@ -0,0 +1,146 b''
1 """The IPython notebook format
2
3 Use this module to read or write notebook files as particular nbformat versions.
4 """
5
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
8
9 from IPython.utils.log import get_logger
10
11 from . import v1
12 from . import v2
13 from . import v3
14 from . import v4
15
16 versions = {
17 1: v1,
18 2: v2,
19 3: v3,
20 4: v4,
21 }
22
23 from .validator import validate, ValidationError
24 from .converter import convert
25 from . import reader
26 from .notebooknode import from_dict, NotebookNode
27
28 from .v4 import (
29 nbformat as current_nbformat,
30 nbformat_minor as current_nbformat_minor,
31 )
32
33 class NBFormatError(ValueError):
34 pass
35
36 # no-conversion singleton
37 NO_CONVERT = object()
38
39 def reads(s, as_version, **kwargs):
40 """Read a notebook from a string and return the NotebookNode object as the given version.
41
42 The string can contain a notebook of any version.
43 The notebook will be returned `as_version`, converting, if necessary.
44
45 Notebook format errors will be logged.
46
47 Parameters
48 ----------
49 s : unicode
50 The raw unicode string to read the notebook from.
51 as_version : int
52 The version of the notebook format to return.
53 The notebook will be converted, if necessary.
54 Pass nbformat.NO_CONVERT to prevent conversion.
55
56 Returns
57 -------
58 nb : NotebookNode
59 The notebook that was read.
60 """
61 nb = reader.reads(s, **kwargs)
62 if as_version is not NO_CONVERT:
63 nb = convert(nb, as_version)
64 try:
65 validate(nb)
66 except ValidationError as e:
67 get_logger().error("Notebook JSON is invalid: %s", e)
68 return nb
69
70
71 def writes(nb, version=NO_CONVERT, **kwargs):
72 """Write a notebook to a string in a given format in the given nbformat version.
73
74 Any notebook format errors will be logged.
75
76 Parameters
77 ----------
78 nb : NotebookNode
79 The notebook to write.
80 version : int, optional
81 The nbformat version to write.
82 If unspecified, or specified as nbformat.NO_CONVERT,
83 the notebook's own version will be used and no conversion performed.
84
85 Returns
86 -------
87 s : unicode
88 The notebook as a JSON string.
89 """
90 if version is not NO_CONVERT:
91 nb = convert(nb, version)
92 else:
93 version, _ = reader.get_version(nb)
94 try:
95 validate(nb)
96 except ValidationError as e:
97 get_logger().error("Notebook JSON is invalid: %s", e)
98 return versions[version].writes_json(nb, **kwargs)
99
100
101 def read(fp, as_version, **kwargs):
102 """Read a notebook from a file as a NotebookNode of the given version.
103
104 The string can contain a notebook of any version.
105 The notebook will be returned `as_version`, converting, if necessary.
106
107 Notebook format errors will be logged.
108
109 Parameters
110 ----------
111 fp : file
112 Any file-like object with a read method.
113 as_version: int
114 The version of the notebook format to return.
115 The notebook will be converted, if necessary.
116 Pass nbformat.NO_CONVERT to prevent conversion.
117
118 Returns
119 -------
120 nb : NotebookNode
121 The notebook that was read.
122 """
123 return reads(fp.read(), as_version, **kwargs)
124
125
126 def write(nb, fp, version=NO_CONVERT, **kwargs):
127 """Write a notebook to a file in a given nbformat version.
128
129 The file-like object must accept unicode input.
130
131 Parameters
132 ----------
133 nb : NotebookNode
134 The notebook to write.
135 fp : file
136 Any file-like object with a write method that accepts unicode.
137 version : int, optional
138 The nbformat version to write.
139 If nb is not this version, it will be converted.
140 If unspecified, or specified as nbformat.NO_CONVERT,
141 the notebook's own version will be used and no conversion performed.
142 """
143 s = writes(nb, version, **kwargs)
144 if isinstance(s, bytes):
145 s = s.decode('utf8')
146 return fp.write(s)
@@ -1,26 +1,11 b''
1 """API for converting notebooks between versions.
1 """API for converting notebooks between versions."""
2
2
3 Authors:
3 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
4
5
5 * Jonathan Frederic
6 from . import versions
6 """
7 from .reader import get_version
7
8
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2013 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
19 from .reader import get_version, versions
20
21 #-----------------------------------------------------------------------------
22 # Functions
23 #-----------------------------------------------------------------------------
24
9
25 def convert(nb, to_version):
10 def convert(nb, to_version):
26 """Convert a notebook node object to a specific version. Assumes that
11 """Convert a notebook node object to a specific version. Assumes that
@@ -40,7 +25,7 b' def convert(nb, to_version):'
40 # Get input notebook version.
25 # Get input notebook version.
41 (version, version_minor) = get_version(nb)
26 (version, version_minor) = get_version(nb)
42
27
43 # Check if destination is current version, if so return contents
28 # Check if destination is target version, if so return contents
44 if version == to_version:
29 if version == to_version:
45 return nb
30 return nb
46
31
@@ -60,11 +45,10 b' def convert(nb, to_version):'
60 # Convert and make sure version changed during conversion.
45 # Convert and make sure version changed during conversion.
61 converted = convert_function(nb)
46 converted = convert_function(nb)
62 if converted.get('nbformat', 1) == version:
47 if converted.get('nbformat', 1) == version:
63 raise Exception("Cannot convert notebook from v%d to v%d. Operation" \
48 raise ValueError("Failed to convert notebook from v%d to v%d." % (version, step_version))
64 "failed silently." % (version, step_version))
65
49
66 # Recursively convert until target version is reached.
50 # Recursively convert until target version is reached.
67 return convert(converted, to_version)
51 return convert(converted, to_version)
68 else:
52 else:
69 raise Exception("Cannot convert notebook to v%d because that " \
53 raise ValueError("Cannot convert notebook to v%d because that " \
70 "version doesn't exist" % (to_version))
54 "version doesn't exist" % (to_version))
@@ -1,4 +1,8 b''
1 """The official API for working with notebooks in the current format version."""
1 """Deprecated API for working with notebooks
2
3 - use IPython.nbformat for read/write/validate public API
4 - use IPython.nbformat.vX directly for Python API for composing notebooks
5 """
2
6
3 # Copyright (c) IPython Development Team.
7 # Copyright (c) IPython Development Team.
4 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
@@ -8,6 +12,12 b' from __future__ import print_function'
8 import re
12 import re
9 import warnings
13 import warnings
10
14
15 warnings.warn("""IPython.nbformat.current is deprecated.
16
17 - use IPython.nbformat for read/write/validate public API
18 - use IPython.nbformat.vX directly to composing notebooks of a particular version
19 """)
20
11 from IPython.nbformat.v3 import (
21 from IPython.nbformat.v3 import (
12 NotebookNode,
22 NotebookNode,
13 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
23 new_code_cell, new_text_cell, new_notebook, new_output, new_worksheet,
@@ -17,8 +27,8 b' from IPython.nbformat.v3 import ('
17 from IPython.nbformat import v3 as _v_latest
27 from IPython.nbformat import v3 as _v_latest
18
28
19 from .reader import reads as reader_reads
29 from .reader import reads as reader_reads
20 from .reader import versions
30 from . import versions
21 from .convert import convert
31 from .converter import convert
22 from .validator import validate, ValidationError
32 from .validator import validate, ValidationError
23
33
24 from IPython.utils.log import get_logger
34 from IPython.utils.log import get_logger
@@ -1,37 +1,10 b''
1 """API for reading notebooks.
1 """API for reading notebooks of different versions"""
2
2
3 Authors:
3 # Copyright (c) IPython Development Team.
4
4 # Distributed under the terms of the Modified BSD License.
5 * Jonathan Frederic
6 """
7
8 #-----------------------------------------------------------------------------
9 # Copyright (C) 2013 The IPython Development Team
10 #
11 # Distributed under the terms of the BSD License. The full license is in
12 # the file COPYING, distributed as part of this software.
13 #-----------------------------------------------------------------------------
14
15 #-----------------------------------------------------------------------------
16 # Imports
17 #-----------------------------------------------------------------------------
18
5
19 import json
6 import json
20
7
21 from . import v1
22 from . import v2
23 from . import v3
24
25 versions = {
26 1: v1,
27 2: v2,
28 3: v3,
29 }
30
31 #-----------------------------------------------------------------------------
32 # Code
33 #-----------------------------------------------------------------------------
34
35 class NotJSONError(ValueError):
8 class NotJSONError(ValueError):
36 pass
9 pass
37
10
@@ -80,7 +53,7 b' def reads(s, **kwargs):'
80 nb : NotebookNode
53 nb : NotebookNode
81 The notebook that was read.
54 The notebook that was read.
82 """
55 """
83 from .current import NBFormatError
56 from . import versions, NBFormatError
84
57
85 nb_dict = parse_json(s, **kwargs)
58 nb_dict = parse_json(s, **kwargs)
86 (major, minor) = get_version(nb_dict)
59 (major, minor) = get_version(nb_dict)
@@ -10,13 +10,13 b' from hmac import HMAC'
10 import io
10 import io
11 import os
11 import os
12
12
13 from IPython.utils.io import atomic_writing
13 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
14 from IPython.utils.py3compat import string_types, unicode_type, cast_bytes
14 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
15 from IPython.utils.traitlets import Instance, Bytes, Enum, Any, Unicode, Bool
15 from IPython.config import LoggingConfigurable, MultipleInstanceError
16 from IPython.config import LoggingConfigurable, MultipleInstanceError
16 from IPython.core.application import BaseIPythonApplication, base_flags
17 from IPython.core.application import BaseIPythonApplication, base_flags
17
18
18 from .current import read, write
19 from . import read, write, NO_CONVERT
19
20
20
21 try:
21 try:
22 # Python 3
22 # Python 3
@@ -46,6 +46,20 b' def yield_everything(obj):'
46 else:
46 else:
47 yield unicode_type(obj).encode('utf8')
47 yield unicode_type(obj).encode('utf8')
48
48
49 def yield_code_cells(nb):
50 """Iterator that yields all cells in a notebook
51
52 nbformat version independent
53 """
54 if nb.nbformat >= 4:
55 for cell in nb['cells']:
56 if cell['cell_type'] == 'code':
57 yield cell
58 elif nb.nbformat == 3:
59 for ws in nb['worksheets']:
60 for cell in ws['cells']:
61 if cell['cell_type'] == 'code':
62 yield cell
49
63
50 @contextmanager
64 @contextmanager
51 def signature_removed(nb):
65 def signature_removed(nb):
@@ -152,6 +166,8 b' class NotebookNotary(LoggingConfigurable):'
152 - the requested scheme is available from hashlib
166 - the requested scheme is available from hashlib
153 - the computed hash from notebook_signature matches the stored hash
167 - the computed hash from notebook_signature matches the stored hash
154 """
168 """
169 if nb.nbformat < 3:
170 return False
155 stored_signature = nb['metadata'].get('signature', None)
171 stored_signature = nb['metadata'].get('signature', None)
156 if not stored_signature \
172 if not stored_signature \
157 or not isinstance(stored_signature, string_types) \
173 or not isinstance(stored_signature, string_types) \
@@ -170,6 +186,8 b' class NotebookNotary(LoggingConfigurable):'
170
186
171 e.g. 'sha256:deadbeef123...'
187 e.g. 'sha256:deadbeef123...'
172 """
188 """
189 if nb.nbformat < 3:
190 return
173 signature = self.compute_signature(nb)
191 signature = self.compute_signature(nb)
174 nb['metadata']['signature'] = "%s:%s" % (self.algorithm, signature)
192 nb['metadata']['signature'] = "%s:%s" % (self.algorithm, signature)
175
193
@@ -181,14 +199,13 b' class NotebookNotary(LoggingConfigurable):'
181
199
182 This function is the inverse of check_cells
200 This function is the inverse of check_cells
183 """
201 """
184 if not nb['worksheets']:
202 if nb.nbformat < 3:
185 # nothing to mark if there are no cells
186 return
203 return
187 for cell in nb['worksheets'][0]['cells']:
204
188 if cell['cell_type'] == 'code':
205 for cell in yield_code_cells(nb):
189 cell['metadata']['trusted'] = trusted
206 cell['metadata']['trusted'] = trusted
190
207
191 def _check_cell(self, cell):
208 def _check_cell(self, cell, nbformat_version):
192 """Do we trust an individual cell?
209 """Do we trust an individual cell?
193
210
194 Return True if:
211 Return True if:
@@ -204,17 +221,21 b' class NotebookNotary(LoggingConfigurable):'
204 return True
221 return True
205
222
206 # explicitly safe output
223 # explicitly safe output
207 safe = {
224 if nbformat_version >= 4:
208 'text/plain', 'image/png', 'image/jpeg',
225 safe = {'text/plain', 'image/png', 'image/jpeg'}
209 'text', 'png', 'jpg', # v3-style short keys
226 unsafe_output_types = ['execute_result', 'display_data']
210 }
227 safe_keys = {"output_type", "execution_count", "metadata"}
228 else: # v3
229 safe = {'text', 'png', 'jpeg'}
230 unsafe_output_types = ['pyout', 'display_data']
231 safe_keys = {"output_type", "prompt_number", "metadata"}
211
232
212 for output in cell['outputs']:
233 for output in cell['outputs']:
213 output_type = output['output_type']
234 output_type = output['output_type']
214 if output_type in ('pyout', 'display_data'):
235 if output_type in unsafe_output_types:
215 # if there are any data keys not in the safe whitelist
236 # if there are any data keys not in the safe whitelist
216 output_keys = set(output).difference({"output_type", "prompt_number", "metadata"})
237 output_keys = set(output)
217 if output_keys.difference(safe):
238 if output_keys.difference(safe_keys):
218 return False
239 return False
219
240
220 return True
241 return True
@@ -226,14 +247,12 b' class NotebookNotary(LoggingConfigurable):'
226
247
227 This function is the inverse of mark_cells.
248 This function is the inverse of mark_cells.
228 """
249 """
229 if not nb['worksheets']:
250 if nb.nbformat < 3:
230 return True
251 return False
231 trusted = True
252 trusted = True
232 for cell in nb['worksheets'][0]['cells']:
253 for cell in yield_code_cells(nb):
233 if cell['cell_type'] != 'code':
234 continue
235 # only distrust a cell if it actually has some output to distrust
254 # only distrust a cell if it actually has some output to distrust
236 if not self._check_cell(cell):
255 if not self._check_cell(cell, nb.nbformat):
237 trusted = False
256 trusted = False
238
257
239 return trusted
258 return trusted
@@ -285,14 +304,14 b' class TrustNotebookApp(BaseIPythonApplication):'
285 self.log.error("Notebook missing: %s" % notebook_path)
304 self.log.error("Notebook missing: %s" % notebook_path)
286 self.exit(1)
305 self.exit(1)
287 with io.open(notebook_path, encoding='utf8') as f:
306 with io.open(notebook_path, encoding='utf8') as f:
288 nb = read(f, 'json')
307 nb = read(f, NO_CONVERT)
289 if self.notary.check_signature(nb):
308 if self.notary.check_signature(nb):
290 print("Notebook already signed: %s" % notebook_path)
309 print("Notebook already signed: %s" % notebook_path)
291 else:
310 else:
292 print("Signing notebook: %s" % notebook_path)
311 print("Signing notebook: %s" % notebook_path)
293 self.notary.sign(nb)
312 self.notary.sign(nb)
294 with io.open(notebook_path, 'w', encoding='utf8') as f:
313 with atomic_writing(notebook_path) as f:
295 write(nb, f, 'json')
314 write(nb, f, NO_CONVERT)
296
315
297 def generate_new_key(self):
316 def generate_new_key(self):
298 """Generate a new notebook signature key"""
317 """Generate a new notebook signature key"""
@@ -1,152 +1,306 b''
1 {
1 {
2 "metadata": {
2 "cells": [
3 "cell_tags": [
3 {
4 [
4 "cell_type": "markdown",
5 "<None>",
5 "metadata": {}
6 null
6 },
7 {
8 "cell_type": "markdown",
9 "metadata": {},
10 "source": [
11 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
7 ]
12 ]
8 ],
13 },
9 "name": 0
10 },
11 "nbformat": 3,
12 "nbformat_minor": 0,
13 "worksheets": [
14 {
14 {
15 "cells": [
15 "cell_type": "heading",
16 {
16 "level": 2,
17 "cell_type": "heading",
17 "metadata": {},
18 "level": 1,
18 "source": [
19 "source": [
19 "Printed Using Python"
20 "nbconvert latex test"
20 ]
21 ]
21 },
22 },
22 {
23 {
23 "cell_type": "code",
24 "cell_type": "markdown",
24 "execution_count": 1,
25 "metadata": {},
25 "metadata": {
26 "source": [
26 "collapsed": false
27 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
27 },
28 ]
28 "outputs": [
29 },
30 {
31 "cell_type": "heading",
32 "level": 2,
33 "metadata": {},
34 "source": [
35 "Printed Using Python"
36 ]
37 },
38 {
39 "cell_type": "code",
40 "collapsed": false,
41 "input": [
42 "print(\"hello\")"
43 ],
44 "language": "python",
45 "metadata": {},
46 "outputs": [
47 {
48 "output_type": "stream",
49 "stream": "stdout",
50 "text": [
51 "hello\n"
52 ]
53 }
54 ],
55 "prompt_number": 1
56 },
57 {
29 {
58 "cell_type": "heading",
30 "name": "stdout",
59 "level": 1000,
31 "output_type": "bad stream",
60 "metadata": {},
32 "text": [
61 "source": [
33 "hello\n"
62 "Pyout"
63 ]
34 ]
64 },
35 }
36 ],
37 "source": [
38 "print(\"hello\")"
39 ]
40 },
41 {
42 "cell_type": "markdown",
43 "metadata": {},
44 "source": [
45 "## Pyout"
46 ]
47 },
48 {
49 "cell_type": "code",
50 "execution_count": 3,
51 "metadata": {
52 "collapsed": false
53 },
54 "outputs": [
65 {
55 {
66 "cell_type": "code",
56 "data": {
67 "collapsed": false,
57 "text/html": [
68 "input": [
58 "\n",
69 "from IPython.display import HTML\n",
59 "<script>\n",
70 "HTML(\"\"\"\n",
60 "console.log(\"hello\");\n",
71 "<script>\n",
61 "</script>\n",
72 "console.log(\"hello\");\n",
62 "<b>HTML</b>\n"
73 "</script>\n",
63 ],
74 "<b>HTML</b>\n",
64 "text/plain": [
75 "\"\"\")"
65 "<IPython.core.display.HTML at 0x1112757d0>"
76 ],
66 ]
77 "language": "python",
67 },
68 "execution_count": 3,
78 "metadata": {},
69 "metadata": {},
79 "outputs": [
70 "output_type": "execute_result"
80 {
71 }
81 "html": [
72 ],
82 "\n",
73 "source": [
83 "<script>\n",
74 "from IPython.display import HTML\n",
84 "console.log(\"hello\");\n",
75 "HTML(\"\"\"\n",
85 "</script>\n",
76 "<script>\n",
86 "<b>HTML</b>\n"
77 "console.log(\"hello\");\n",
87 ],
78 "</script>\n",
88 "metadata": {},
79 "<b>HTML</b>\n",
89 "output_type": "pyout",
80 "\"\"\")"
90 "prompt_number": 3,
81 ]
91 "text": [
82 },
92 "<IPython.core.display.HTML at 0x1112757d0>"
83 {
93 ]
84 "cell_type": "code",
94 }
85 "execution_count": 7,
95 ],
86 "metadata": {
96 "prompt_number": 3
87 "collapsed": false
97 },
88 },
89 "outputs": [
98 {
90 {
99 "cell_type": "code",
91 "data": {
100 "collapsed": false,
92 "application/javascript": [
101 "input": [
93 "console.log(\"hi\");"
102 "%%javascript\n",
94 ],
103 "console.log(\"hi\");"
95 "text/plain": [
104 ],
96 "<IPython.core.display.Javascript at 0x1112b4b50>"
105 "language": "python",
97 ]
98 },
106 "metadata": {},
99 "metadata": {},
107 "outputs": [
100 "output_type": "display_data"
108 {
101 }
109 "javascript": [
102 ],
110 "console.log(\"hi\");"
103 "source": [
111 ],
104 "%%javascript\n",
112 "metadata": {},
105 "console.log(\"hi\");"
113 "output_type": "display_data",
106 ]
114 "text": [
107 },
115 "<IPython.core.display.Javascript at 0x1112b4b50>"
108 {
116 ]
109 "cell_type": "markdown",
117 }
110 "metadata": {},
118 ],
111 "source": [
119 "prompt_number": 7
112 "### Image"
120 },
113 ]
121 {
114 },
122 "cell_type": "heading",
115 {
123 "level": 3,
116 "cell_type": "code",
124 "metadata": {}
117 "execution_count": 6,
125 },
118 "metadata": {
119 "collapsed": false
120 },
121 "outputs": [
126 {
122 {
127 "cell_type": "code",
123 "data": {
128 "collapsed": false,
124 "image/png": [
129 "input": [
125 "iVBORw0KGgoAAAANSUhEUgAAAggAAABDCAYAAAD5/P3lAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\n",
130 "from IPython.display import Image\n",
126 "AAAH3AAAB9wBYvxo6AAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAACAASURB\n",
131 "Image(\"http://ipython.org/_static/IPy_header.png\")"
127 "VHic7Z15uBxF1bjfugkJhCWBsCSAJGACNg4QCI3RT1lEAVE+UEBNOmwCDcjHT1wQgU+WD3dFxA1o\n",
132 ],
128 "CAikAZFFVlnCjizpsCUjHQjBIAkQlpCFJGS79fvjdGf69vTsc2fuza33eeaZmeqq6jM9vZw6dc4p\n",
133 "language": "python",
129 "BUwC+tE+fqW1fqmRDpRSHjCggS40sBxYDCxKvL8KzNBaL21EPoPB0DPIWVY/4NlE0ffzYfhgu+Qx\n",
130 "GHoy/YFjaK+CcB3QkIIAHAWs3wRZsuhUSs0CXgQeBm7UWi/spn0Z+jA5yxpEfYruqnwYllRic5a1\n",
131 "MaWv8U5gaT4M19Sx396IAnZLfB/SLkEMhp5O/3YL0AvoAHaKXl8HLlZK3QZcpbWe0lbJDOsaHuDU\n",
132 "0e4u4JAy2wPk/C1JzrKWArOQ0fUtwH35MOysQxaDwbCO0NFuAXoh6wPjgQeUUvcqpUa0WyCDoQls\n",
133 "CIwBjgfuAV7KWdY+7RWpmJxlXZezrEdylvXxdstiMKzrGAtCYxwI/EspdZbW+g/tFsbQ67kQuBHY\n",
134 "FNgseh9FV6vCbUAeWBC9PgBeq2EfS6J2MQOBrRDTe5KdgAdzlvW1fBjeUUP/3UbOsoYBE6OvG7VT\n",
135 "FoOhL9Af+BUwFLkZpV+DaY6V4UPkRpb1+ncT+m8nGwK/V0oN01qf025hDL2XfBi+DLycLMtZVo6u\n",
136 "CsKfGnSq8/NheEpqHwOBEcDBwJnAsGhTP2ByzrJG5cPwnQb22Sy+0G4BDIa+RH+t9dmlNiqlFKIk\n",
137 "JJWGi+jq5JPmq8BbJJQArfXqpkncczlbKbVQa/3rdgtiMNRCPgxXAK8Ar+Qs63LgXmDvaPPGwPeA\n",
138 "H7VJvCRfbLcABkNfouwUg9ZaAwuj178BlFLvVejzgR4WFviM1npcuQpKqf6IyXIjxLS7GzAWuUnu\n",
139 "XsO+fqWUellr3ZBJdq/jr9+BDn1uve07O9Rz0y6f8PtGZGgWe53oT6SBkZ/q1/nHZy47aloTRTKU\n",
140 "IR+Gy3OWNR6Zxtg0Kv4KRkEwGPocxgcBiCwcsSI0F5iOhF+ilPok8C3gVGS+thK/VErdrbWuO2ys\n",
141 "s/+aLZTuOKbe9krrIUCPUBB0B+PQ1P1bdKe6EzAKQgvJh+GbOct6gkJkxM45y+qXDIWMHBhjBWJe\n",
142 "PgyDWvaRs6zPIVObAG/nw/DpEvUGAp8E9gGGJzbtl7Os7cvs4skqp0V0Yl8jgcOBjyMDhbmIZeWl\n",
143 "fBg+UUVfReQsayhwELAnsAXi6/E28BxwTz4MP6iyn92RaSCA+/NhuCwqXx9R4MYhU0MfRTK/AjyW\n",
144 "D8MFGd0ZDFVhFIQKaK3/BXxfKXUlklTq0xWafAI4Driyu2UzGLqRlygoCArYHJif2H4gcFb0+Z2c\n",
145 "ZW2bD8NV1XScs6yNgH8g/jsAPwCeTmzfFPgjYsnbiez71MUVdnMQcF8V4nyUs6whwB8QX4+0s2Ys\n",
146 "0yPAt/NhGFbRZ/wbzgO+DaxXotqqnGX9GbigCkXhf5CBCsDngYdzljURGQhsWqLN+znL+iFwdT4M\n",
147 "dYk6BkNJTJhjlWitQ2Bf4P4qqv848t8wGHor6Yd9+ruHJFkC2BI4rIa+D6egHKwmstYlGAxMQCwH\n",
148 "rRjEPI5ER5S7ZvcFXsxZ1phKneUsawSi8HyH0soB0bbvAM9Ebaplt5xlnYkct1LKAYiFZhJwSQ19\n",
149 "GwxrMRaEGtBar1RKfRX4JxIzXortou3PN1mE+YgJsSwaeoLHOQCqUy3QSr9eqZ6G/gq2aYVMhqrY\n",
150 "OfF5FeJwvJZ8GM7JWdY/gC9HRS7wtyr7Pjrx+e6MqYC3KLbU7Qhck/h+FJIKvRRVjfSREXicU8EH\n",
151 "pgAvIIqLBZwGfC7avl5Uf29KkLOsTZCMq8npj9sQx89no37HIlaAODplNPBIzrJ2z4dhNVlaT0HC\n",
152 "XwFmIkrAC4if2PaIz8/3KCgn385Z1pX5MJxeRd8Gw1qMglAjWutlSqnTgUcqVP0SzVYQtP5mcMXE\n",
153 "SvvtUUy9YsK5QEWHy7EnTB6lOtSsFohkqEDOsgYAdqJoagkT9Z8pKAj75yzr4/kwnF2h748ho/GY\n",
154 "q9J1oqiKLj4JOctKK8Yz8mH4Yrl9VcnHkXVYTsyHoZ8WJWdZNyPThbF5/3M5yzowH4alpi9+T0E5\n",
155 "WA18Nx+Gf0zVeRG4KmdZ90R9bwCMRKwyX69C5h2j91uA4/JhuCSxbTYwJWdZtwNPIFbifsAFSISZ\n",
156 "wVA1ZoqhDrTWjyIjjXIc3ApZDIZu4ELgY4nvt5Wody8wJ/qsgBOr6HsihfvOfCRrY7v5dYZyAECk\n",
157 "GP0ISEZmZYZ55yxrB8SyEXNxhnKQ7Pt64H8TRUfmLGuXKmWeC4xPKQfJvp9CLCJlZTYYymEUhPq5\n",
158 "tcL2XVsihcHQJHKWtU3Osi5GnAZj5iKWgiKitRouTxQdl7OscnPu0HV64dp8GLY7R8pyxEGxJPkw\n",
159 "fBcZ9ceUSvN8IoV76upK/UZcgawcG3NKqYopfleFU+gDic/b5SzLWIwNNWFOmPqp5CG9sVJqPa11\n",
160 "VZ7dBkOL2D1nWcmcBkOR8MFtgM/QdTXJZcCR+TBcXqa/SYj5egAFZ8VMX4ScZe2FRPnEXF2z9M3n\n",
161 "3nwYVsrtAmK6/0z0uVR4ZXLtivvzYfhGpU7zYbgkZ1k3ACdHRQdWIQsUO3ZmkUzB3Q/xjaolLbeh\n",
162 "j2MUhDrRWr+mlFpJ+eV5hyIxz4YWs98Fj/Rf8uZbozo0/ZYt7D8rf9ORK9stUw/hU9GrEnMAp1R+\n",
163 "gph8GL4bzdNPiIpOorSzYtJ68FS1IYPdTLWp3hcnPm+Q3pizrA7E+TCmFn+aZN0dcpY1LB+G5e4b\n",
164 "y6rM8bA49X39GmQyGMwUQ4NUGnkMrbDd0A3sdeLk4z6cN+89pTtDTWd+gyErF+7pTv5eu+XqJbyK\n",
165 "TDHsmg/DJ6tsc2ni8+dzljUqXSGaevhmoqjIObFNVBzlV8kQug4W5tbQNl13WGatAv+poW+DoW6M\n",
166 "BaExPgC2LrO9nHWhpSilDqI4NPMhrfXUJvS9M/DfqeJXtdY3N9p3rex50uQ9lFKT6BrTvoFCXbTX\n",
167 "yZNfmnrZxHtbLVMP4xng74nvK5DzeD7wfIWRayb5MHwiZ1kzgF0oOCuemar2ZQoK8zLgr7Xup5t4\n",
168 "s0n9DEl9b0RBSPeV5q0a+jYY6sYoCI1RacnZ91siRXUMAH6eKnsYicdulDOAY1NlpzWh35pRqG9R\n",
169 "IuGN7uw4AfG878s8nw/DX3RDv5dScGY8NmdZP86HYXJaJzm9cHMp7/s2UHdK9BTpKaxBNbRN163k\n",
170 "t9Rux05DH8FMMTTGZhW2v9sSKarjbopNk/sqpUY30qlSahCSGS/JCuD6RvqtF6UpMm/HaHTJbYaG\n",
171 "mQzED/0umRVzlrUZhXwJ0HOmF5pJOlXyxzJrZbNt6rtZP8HQIzAKQp0opTZAlsItxTKtdTnv75YS\n",
172 "LR7lpYqrjV0vx2EUH4fbtdZtucnpMqOrDjPy6jYii8DkRFHSYnAEhem22cBjrZKrVeTDcCldTf/p\n",
173 "h345ksrEGprnF2EwNIRREOrnMxW2z2uJFLVxJcXmy2OVUo34ShydUda+EaIq7T2u0SZTY/eSdFY8\n",
174 "MGdZm0efk86J6/LCQUnFp5pIkZjkcvQz8mH4YZPkMRgawigI9VNp7v7BlkhRA1rr+RQneNqC2hba\n",
175 "WYtSajiS9z3JXLomaGktq/VllLIUdKqSWe0MjZMPwxlIel8Q/6Zv5CxrGIX8AJ10XU+hFtIRQ+UW\n",
176 "KWoXyYyTu+Qsa79KDXKWNRpJyx5zZ9OlMhjqxCgIdaCU6g98o0K1npBCNotLM8rcOvuagCRgSXKN\n",
177 "1rozq3IrCCZNfFkrfRjotWsCaJinUBODK51/tkuuPkTy/DoYOIDCfeb+fBjW4t2/lqhdcmRdbUri\n",
178 "VnILXS2HZ1WRvfAcCk61K4A/dYdgBkM9GAWhPr5F6XSrIBf6Qy2SpSaidSReShV/XilV7veUIj29\n",
179 "oOkB2fGmXT7x7sCbOGpFf7VZx4A1m0/znG2nehMyc+0bms7NFJxzxwH7J7Y1OvWUPG9/mLOsLRvs\n",
180 "r6lEaaOT0TtfBB5ITLWsJWdZg3KWdRNwTKL4wnwYzu9mMQ2GqjFhjjWilBqBpJYtx51a66UV6rST\n",
181 "S+maJz52VvxRdvVilFK7UbzexGNa67Kr+bWS6X+ekPYs79HkLGt34JOI+Xyz6D2d1vfMnGUdini6\n",
182 "L0C851/Oh2HD+SyaQT4MV+YsaxJyLm1Gwf9gAXBHg93/JNHHtsArOcuajCztPBDYCkkytBXg5sOw\n",
183 "5QmF8mF4W86yLgK+HxXtC8zKWVaALMm8CslHsicS7RFzL8VhyAZDWzEKQg0opbYE7qd8prPVdF2h\n",
184 "rSdyLfALYMNE2XFKqR/XsHbEURll62L4Wiv5PuBUqPPF6JXkLuCQbpGoPi4HfohYKGMHWD9axrlu\n",
185 "8mF4Z7RuwfioaDBwaonqRemQW0U+DH+Qs6xFwHnIFNwQsv+3mMnA8dHiVwZDj8FMMVSJUuow4DkK\n",
186 "a7GX4gqt9cstEKlutNaL6boULMho5tBq2iul+lH8IFuCmJcNfZx8GM6hOCFVU5THfBhOQHxfylkH\n",
187 "3gY+asb+6iUfhhcCewC3l5BlFbJk/P75MDwqlVTKYOgRKK1rizhSSk2h67ximo1abV5XSi2n9EIk\n",
188 "z2itx5XYVqnfQcjI7DiqW2XtfeCTUbRA3ex50nWfUrqjeJEcrfcLrpj4SCN9xyilxgDPp4of0Fof\n",
189 "UEXbg4B/pIqv1FrXnVNh7AmTR3V0qIwwRH1E4E28pd5+De0hZ1m/Bb4bfX0+H4Z7dMM+hgGjkDwC\n",
190 "S5FpjFk9bR4/Z1mDkGmF4VHR20g4Y3oxJYOhR9EXphg6lFLlVjFbH0mZvDGwCTAayCFe0ntTOZ1y\n",
191 "zDLgkEaVg1ahtX5BKfUU8OlE8ReUUjtorSstCduzch8YehSR5/6ERFG3nBvRuhE9frXUfBguA6pd\n",
192 "+Mpg6DH0BQXBBro7o+Ea4Bta66e6eT/N5lK6KggKOAE4u1QDpdTGFOdNmNkLf7uh+zgYcRQEMa+3\n",
193 "Je22wWBoDOOD0DhLgYla67vaLUgd3ETxglLHRXkeSnEExQ5gbQ9tNPQokis5TsqHoVlbwGDohRgF\n",
194 "oTECYHet9Y3tFqQetNYrKDb/DqN46eYk6emF1UhUhMFAzrImUEhDvgr4VRvFMRgMDWAUhPpYAvwf\n",
195 "8Bmte31+/8uQBEdJMjMrKqW2o5A2N+YfWusePw9s6F5yltWRs6zxwKRE8RXtyEVgMBiaQ1/wQWgm\n",
196 "eWTe/jqtdU9Zz74htNavKaXuAw5KFB+glBqptZ6Tqj6RQlrYGDO90AfJWdY5wNeQFQwHIAmetk5U\n",
197 "eZFCsiCDwdALMQpCed5AphEC4NF12BHvUroqCAoJ7TwvVS+d++BdJEmPoe+xKRLnn0UeODwfhm3N\n",
198 "RWAwGBqjLygIbwN/LbNdI1MGH6ReL/eWkMUmcDeSeGa7RNlRSqnzdZQoQym1C7Bzqt11NWReNKxb\n",
199 "zEMU6GHAesBiYCaSLOviaF0Cg8HQi+kLCsLrWuvT2y1ET0ZrvUYp5SG57mO2Bz4LPB59/2ZRQ5P7\n",
200 "oM+SD8OLgYvbLYfBYOg+jJOiIeZKxOs8STJiIb28daC1/lf3imQwGAyGdmEUBAMA0XTKraniI5VS\n",
201 "A6O0zOnloI31wGAwGNZhjIJgSHJp6vtgJBNlehW65cANLZHIYDAYDG3BKAiGtWitHwVeShV/muLF\n",
202 "uW7VWi9qjVQGg8FgaAd9wUnRUBuXAn9IfN8f+FyqTo/OfbDnSX8brDpXnqEUe2ropzQvdtDx66ev\n",
203 "GN9XolIMPQDb9T8LrBd4zsPtlsXQe7Bd/0BgQeA5QbtlMQqCIc21wC+ADaPv6WWu5wAPtVKgWtjt\n",
204 "6Os2XG/9jhdQjIzTQ2rFF9bQecy4E2/I9UQlwXb9LYDDK1R7K/Cc21shj6FxbNcfDjwGKNv1Rwae\n",
205 "83q7ZWo2tusPBb6ELGW9BbAICX99Gngs8Jx0hlZDBWzXHwvcC6ywXX9o4DlL2ymPURAMXdBaL1ZK\n",
206 "+ZRItwz8Jc6N0BMZMFB9GxiZsWnzTjrPAH7QWomqYgTF/h9pngC6RUGwXf+XwC2B50ztjv57M7br\n",
207 "XwJMCjxneo1NP0SWgAfJq7LOYLv+esAFwOkUL9wWM912/d0Dz+lsnWQ9A9v1BwEXAT8PPKfWVOML\n",
208 "kPVt3kNWQm0rxgfBkEWph5UG/tJCOWqnQ40ttUkrvWcrRamWwHOmAZsguSfGAi9Hmy5AUhgPAz7f\n",
209 "Hfu2XX8k8ENgx+7ovzdju/4uwP9D/peaCDxnCbANsF3gOYubLVu7sF1/AHAHcBaiHDwI/C+ywNsE\n",
210 "4KfA68BdfVE5iNgbOBmxqtRE4Dn/BoYDnwg8Z02zBasVY0EwFKG1fkEp9RTioJjkIa11zzaVarYq\n",
211 "vVFt2TpBaiN6oCwB5tiu/2FUPCvwnLTTaLM5oJv77800dGwCz1kXHXkvRNKydwI/Cjzn1+kKtuuf\n",
212 "i2TX7Ks0et681yxBGsUoCIZSBBQrCL0h98EbdW7rddiuPwoYFJu/bdffFNgL2BZ4DZgWKR5ZbRWS\n",
213 "2+KIqGiE7fpjUtXmlrtZRdaHscBAYDowM/CckimWbdffFfgw8JzXou/9kfUccojV5MXAcz4s0XYw\n",
214 "sCsymu8PzAVmBJ7zVqn9pdoPRVKF7wSsAN4EgqzRve36HcAoZDEqgO0zjs3rged8kGo3gOJ05ADT\n",
215 "s0bTkan+k9HXGaVGjNFxykVf81nH2Hb9Ich/MRJJeT291H9fL7brj6CwANfPspQDgOi3rijRx/rI\n",
216 "b8kB7wPPBZ4zL6Ne/JvfCDzn/WhufhvgvsBzVkR1dgN2AR4JPGduom38P7wXeM7c6FzfCfgU4iMR\n",
217 "lFLebNfPIefXzMBzikz8tusPQyx676bljmTeCfhyVLST7frp//TV9Dluu/6GwOhUvTWB58zIkjFq\n",
218 "sykyNfmfwHMW2K7fLzoWeyDTFPnAc14t1T7qYwNgT+Rc/wi5ZyT/N20UBEMRSqn+wNdTxQspTqTU\n",
219 "41BaP6yVOipzGzzSYnG6m6uBz0YPv7OQm3dytc35tuuflHZutF3/BuArwEaJ4p/QNdU2wGnAH9M7\n",
220 "jRSTG5CbS5LQdv2joymTLKYBzwHjbNc/DomW2TCxfbXt+sMCz3k/sa8RwM+Qh/X6qf5W2q4/CTit\n",
221 "zMN1OPB7CopQktW2658YeM5fEvXvRKZzBiXqZaWUPha4JlW2NfB8Rt0hiANfmjWIuf5jiLPfvVm/\n",
222 "AfmvbgNmB54zKrkheuD+Bjg11Wap7fpnBJ5TybelFk4E+iE+Fb+ptbHt+scg//nGqfJbgeMDz1mY\n",
223 "KN4UOZYX2q7fSWHhuNdt198ZOBc4MypbbLv+5wPPeTb6PiJqe5ft+ichx3WXRN8rbdc/OfCcrGis\n",
224 "R4ChiHKSlSn2f4BzkOvitMRvCKJ9DEzU9TPafwGZlkkyBvExSrKUrtdnmoOBycA5tus/iCyat3li\n",
225 "u7Zd/0rk2ihS1mzXPwT4E3LulaLTKAiGLL6EaMlJbtBat91pphIjFw289t9DVh4N7Jva9EKnWnpJ\n",
226 "G0RqBXcjCa08YCqy/PJE4L8A33b9HQPPeTNR/0bgvujzGchoywPSq5U+nd6R7fp7IDfRjYDrEE99\n",
227 "DeyHrPb5lO364xI36zTb2q4/AUnt/SSyLHQHMvJZklQOIhYChyCLid2FWBoGIQrDfwGnAP8Gskzd\n",
228 "VvSbBgPvIMdpJjLHuxdikXgg1ewa4Jbo84+BHRAFI/3gT9/QQZa+/iIy9zwccVQrSeA5nbbrX4s8\n",
229 "cI6htIIQK7xdFJLIAvEEYjmYBlyP/E4LeXj92Xb94YHnnFtOjhrYJ3q/vtbpE9v1fwqcjYxUL0GO\n",
230 "51bI//g1YIzt+mNTSgJIivfNEIXgBOThfx0ySv8Nct7vgzgfj0+1HQf8E5iPKM/vI+vLHA9cZbs+\n",
231 "JZSEevgDBZ++3yIKzgVI1FeSrCnD6ci0zebAJxCfjmoZjxzXPPBL5By0gW8jCt3sqHwtkYL1N0RB\n",
232 "/R2ymOG2yHE5CLFAHAu8ahQEQxbfyijrDdML3HTTkWvUBRfsb88bPb6TzjEK+oHKL184YHL+Jmdl\n",
233 "u+XrJsYBhwaec0dcYLu+hzw0dkcu/AvjbUmLgu36DqIgPB54zuQq9nURMgI8LjnyBibZrj8z2s/l\n",
234 "tuvvVcJJbWvkXDoi8JzbKu0s8JxFtut/IqXgAPzOdv0/IiPnb5KhICAjpMGIEjAhPV1iu35HWsbA\n",
235 "c25ObD8ZURAeqibENBqpTYnark8FBSHiakRBOMx2/cHpB29kSv4KooSlLRYnIcrBHcBXk7/Fdv0b\n",
236 "gReAM23Xvz7wnJlVyFIJK3qfXUsj2/U/jiiiq4B9ktEytuv/Fhlpfx2xEnw31XxHYLfAc6bbrv8k\n",
237 "cny/Bnwz8Jy/2q6/DTLd9F8Zu94ceXAeEHhOvM7MNbbrT0UU4vNs15+c2FY3gedcm/hNP0EUhDvL\n",
238 "KMrJtkuIFPboWNWiIOSAO4HDE7/Dj67FSxEn21+m2pyOWDpuCDxn7fG2Xf8e4F1EIVsceE5oohgM\n",
239 "XVBKjURuSEke11qXMhv3OPR553VO9Sb407yJZwTexO8FnnNV/qYj11XlAOCfSeUA1s4D/y36mp7f\n",
240 "rAvb9fdGLDMzU8pBzMXIg2wsMhLKQiFhgxWVg5gM5SDm+uh9VHqD7fr7IlaNFcAJWb4UPcHLPvCc\n",
241 "2YgVZn3gyIwq30AsQg8lQ+aiefUfR1/PzlB08sD9Udusfmsi2t+Q6GutjspnIE6L16dDaSN/irMR\n",
242 "p8dTbddPOxK/nwgxTZr8747e30SsEkNL7PvXGQrAVYgvwggK/gK9mXMyfuON0fvWkY9Dkp2i97uT\n",
243 "hYHnLKNgURsDxknRUMz5FJ8XP22DHIbqSc9pxsSOW8ObtJ89ovdXbNcvpQC8j4zcdiTbnAoy4q2b\n",
244 "6Ia3CYV5/Y0zqsXOf4/WEYveaq5GQuOOQaZekhydqJNkW2BLZF2UzhL/R+xE2XAIa+A52nb9lUho\n",
245 "Y63hd7GD5d1ZGwPPmW27/iuIUrkLXc/n9xP13rZd/yNgVezoF8n1NjAyyyKETGGl97fGdv1/IlaL\n",
246 "3h7e+06WM2PgOQtt11+GTMcNo6vVJ1aWsyK+4nvFQjAKgiGBUmoshfnOmGe11vdl1Tf0GOaUKI9v\n",
247 "lqrE9lqJb6b/Hb3KsU2Zba/VslPb9bdDfA0ORLz0N62iWWxVqMkc3iZuRuawP2u7/g6JKI9RSCTR\n",
248 "YoodhOP/YgNKK2Ix2zZJzjnINMN2NbaL/4uiaIUE/0EUhB3pqiCkMwl2IscjXZZFJ/B2iW1xRtWR\n",
249 "ZWTqDcwps63U9f8Q0TSN7fp/iK0PtuvviPjmrCHyR1qrICilNkTmHjZDLsDke/JzOtwnzY1KqXcR\n",
250 "R4cFiBab9XlRT87I19dQSo1GNPz0tJOxHvR8mhrOVobB0XuAOBiWo1zmwaqdXW3X3x+4BzGVv4SM\n",
251 "pN9AnPEg21McxMIArTs2dRN4zoe26/8NOA6xGJwfbYqV9b8GnrM81Sz+Lz5A0qOXo2y4Ww3MoT4F\n",
252 "IY4+KTfNF58TaXN4VthstVNDitLKcdxvOjKmEj0tv0M953fs87E3Eul0B2JliBflOzfwnFcA+iul\n",
253 "5iEmwQFNEBaK569L0amUWggcqrXO8gg2FKHG2CdW4Uem9XvBlUflu7RUaiByU3lPa92ZKN8cSav8\n",
254 "fUQBTHKr1rrqueIsxp18/eg1azrLjSYB6NfRsY3G6Is9nDjDYxh4zundvbMotvtm5N50duA5P09t\n",
255 "T0faJIkfirU+zNrF1YiC4FBQECZE73/JqB//F+u14r+ImIVEOB1iu/6ZNfhwzEamp7YuU2e7RN1m\n",
256 "oZBnW5YVIfZ1qNWfotw51yuIph++hET0bAkcikwpTAEuCjxnSly3PzIP0a8NcnYgD6SBlSoaIhQX\n",
257 "V2UtVup24LBU6S7IyG+NUuodZP52awojrTSvIjeshlij9XdQKh2jXYRRDtpGfOCruQfEpmzbdn0V\n",
258 "dP9iPLsgjnEryI67Lzd/PCt6/5Tt+v3LJXAqQ/z7ut2ZO/Ccx23XfxUYZbt+7D8xCngl8Jwsa80s\n",
259 "ZBS8ke36O7cg4ybA5UgegJ0QE/XN5auvZRaiIMQRF12wXX8TCv9ls6eERpOtIMR+EXNS5YsRh8dS\n",
260 "To/V+CzUck21i6uR5++4wHNeKFXJRDH0PfoR5fqmtHKwDDhCa73O5JA3lCSeF04v6Z3FPRTMzBO7\n",
261 "S6AE8Q12PbomgYn5Xpm29yMPhu2RUK96iKMn9q6zfa38JXo/NHoly7oQeM5K4Iro60+jKINuJVJC\n",
262 "Yu/439uuX805A4VkWyfbrp+V/MdFnOmeCmpfFKsSRYMc2/U/DeyG3OfSjpOx5WmfVHmcuXFcFfus\n",
263 "5ZpqObbrb45EtswqpxyAcVI0FDMbOFxrXeT9a+heopvnEArzolvashT0wmbEapdgGpIU5XDb9R9F\n",
264 "YqrXQyyL8wPPeTeuGHjOMtv1T0VuqldH6W//jigNmyHOcAcBgwPPcZog20xkRLcJ8DPb9S9CRqM7\n",
265 "I7kDvoDE1hfdxwLPWWy7/plI7oCLbNffHXm4zUQeRtsjGRP/EXhOKSfcABkpj49i5+9G/putgHmB\n",
266 "5yxIN4iSF21C14V6Rtiu/yYSW15uHv4a4P8oKAedlPcvOAv4KmItfCTKKfAS8v8NR1ILHwnsl5GA\n",
267 "qF7ORdYaGA48HGWyfBqYgViDRwCfQR72PkDgOU9E2TvHI4m0TgeeRczb30DyH2iKcyA0ymrgWNv1\n",
268 "FyDK1NvIQ3tStN3LCH+9HUl29UPb9echFo8BUbtLEKfJtJ9EmgA59ifbrj8bCR3cGDlvZqdTLcPa\n",
269 "9NCbUMhs2GFLKvPFSAKxZl7/CxEL8pgoA+QMxD+kE3HenAHcHnjOGmNB6Dt8iGjHWSFKK4HHkcQr\n",
270 "OxvloLXYrr+77fqrEIejNyiE6P0WccZbabv+lFLtG+Ry5AY/BHkYfRDtR9M79QAAA3FJREFUcwYS\n",
271 "NdCFwHPuQR6a7wHfAR5GMhk+i9xcT6G6KIOKBJ6zFBn9r0GUmBlIWN9ziHf/5yjO/phsfy2yqt4i\n",
272 "xOJxF3INTI9k/Q7ZoV4xv0PC5LZCci4sQm6g08kYHdquvxy5lt4DwsSmF5EENCts1//Idv3M9LbR\n",
273 "egJTkEx4NvBA1joFifqLIjkeR6wcfwdeQfIFTEEcjHNU79RXkShvw95Ixs5+yOj/KuSh+ATiAHcq\n",
274 "xb4fxwOXRfJMQc6zlxGF6B3g4MBznmmWnBFzEUfP0xDFcCGiAG+JHKushESXIdanjRBF4l3EInAj\n",
275 "8vuOqWK/5yNRGaOQFNkfIhkOX6CQgwAA2/W3jkI3V0T7ejjatAFyXb2PXP/LbVnroWGi6bbzo697\n",
276 "IlaWk5Br93wkk+jztusP7o94Lna7eaoMZU0cVXIAped7eqGZfP2ZqmPFl+ptrVf3n19UpvVMYLRS\n",
277 "agBywxuEjLwWAe9qrTMXV2mUzs7OP/Xrp+6qt33Hmn5Zue3XNeZTOVoky5nqKiQkrNT883Qk3WvJ\n",
278 "sMLAc1bbrv9Z5AH6KWRkOB+5wRWlWo7a3Ga7/mOIomAho/GFyI30YeDREru7ELlOq07TG3jONbbr\n",
279 "T0Nu9KOQm+i/gFsDz3nTdv2fI2FbpdpfHnlpH4LcnHdAlIz5yLErqXgFnvOR7fo28lDYE7lu3kKO\n",
280 "TdZ9K52xrhTl7knnUVB6SqVeTsr4apQU6lDEbG4hCsFbROsRBE1ebjrwnNB2/XGIGf5gRBkYhPyv\n",
281 "7yDpjR9MtVkOnGK7/vWIgrFrVPcF4O8ZKbaXIuduWkH6KfL/JbkEsWClfWK2CDzHt10/jzhXjkGO\n",
282 "yzNIZEiRD00ga3ocaLv+kUh2xo8hSuVURKmIUyiXVGYCWVzKQlJD7xrJNg85b9LX8RLgF6X6SpFU\n",
283 "9Cpe28gaJgORqEEAbNffDLlvHIQoAndR8NEYilwjExD/nwuUiTQ0GAwGw7qC7fqjEUvKqsBzmhWd\n",
284 "t05gu/5pyNoifw48J9N5PForxQeeNFMMBoPBYDD0DWL/llvK1In9jt4zCoLBYDAYDH2DePo5MwrJ\n",
285 "dv0hFPwTnjBRDAaDwWAw9A3+hPgOHRPl25iK+FhsiuR4OARx0Lwf+J1REAwGg8Fg6AMEnvNklL78\n",
286 "HMRRca/E5hVINNIVwI2B56z6/3ExLRI31pXNAAAAAElFTkSuQmCC\n"
287 ],
288 "text/plain": [
289 "<IPython.core.display.Image at 0x111275490>"
290 ]
291 },
292 "execution_count": 6,
134 "metadata": {},
293 "metadata": {},
135 "outputs": [
294 "output_type": "execute_result"
136 {
137 "metadata": {},
138 "output_type": "pyout",
139 "png": "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\n",
140 "prompt_number": 6,
141 "text": [
142 "<IPython.core.display.Image at 0x111275490>"
143 ]
144 }
145 ],
146 "prompt_number": 6
147 }
295 }
148 ],
296 ],
149 "metadata": {}
297 "source": [
298 "from IPython.display import Image\n",
299 "Image(\"http://ipython.org/_static/IPy_header.png\")"
300 ]
150 }
301 }
151 ]
302 ],
152 }
303 "metadata": {},
304 "nbformat": 4,
305 "nbformat_minor": 0
306 } No newline at end of file
@@ -1,11 +1,5 b''
1 {
1 {
2 "metadata": {
2 "metadata": {
3 "cell_tags": [
4 [
5 "<None>",
6 null
7 ]
8 ],
9 "name": ""
3 "name": ""
10 },
4 },
11 "nbformat": 3,
5 "nbformat": 3,
@@ -1,29 +1,25 b''
1 """
1 """Test the APIs at the top-level of nbformat"""
2 Contains tests class for current.py
3 """
4
2
5 # Copyright (c) IPython Development Team.
3 # Copyright (c) IPython Development Team.
6 # Distributed under the terms of the Modified BSD License.
4 # Distributed under the terms of the Modified BSD License.
7
5
8 import io
9 import json
6 import json
10 import tempfile
11
7
12 from .base import TestsBase
8 from .base import TestsBase
13
9
14 from ..reader import get_version
10 from ..reader import get_version
15 from ..current import read, current_nbformat, validate, writes
11 from IPython.nbformat import read, current_nbformat, writes
16
12
17
13
18 class TestCurrent(TestsBase):
14 class TestAPI(TestsBase):
19
15
20 def test_read(self):
16 def test_read(self):
21 """Can older notebooks be opened and automatically converted to the current
17 """Can older notebooks be opened and automatically converted to the current
22 nbformat?"""
18 nbformat?"""
23
19
24 # Open a version 2 notebook.
20 # Open a version 2 notebook.
25 with self.fopen(u'test2.ipynb', u'r') as f:
21 with self.fopen(u'test2.ipynb', 'r') as f:
26 nb = read(f)
22 nb = read(f, as_version=current_nbformat)
27
23
28 # Check that the notebook was upgraded to the latest version automatically.
24 # Check that the notebook was upgraded to the latest version automatically.
29 (major, minor) = get_version(nb)
25 (major, minor) = get_version(nb)
@@ -33,7 +29,7 b' class TestCurrent(TestsBase):'
33 """dowgrade a v3 notebook to v2"""
29 """dowgrade a v3 notebook to v2"""
34 # Open a version 3 notebook.
30 # Open a version 3 notebook.
35 with self.fopen(u'test3.ipynb', 'r') as f:
31 with self.fopen(u'test3.ipynb', 'r') as f:
36 nb = read(f, u'json')
32 nb = read(f, as_version=3)
37
33
38 jsons = writes(nb, version=2)
34 jsons = writes(nb, version=2)
39 nb2 = json.loads(jsons)
35 nb2 = json.loads(jsons)
@@ -1,30 +1,18 b''
1 """
1 """Tests for nbformat.convert"""
2 Contains tests class for convert.py
2
3 """
3 # Copyright (c) IPython Development Team.
4 #-----------------------------------------------------------------------------
4 # Distributed under the terms of the Modified BSD License.
5 # Copyright (C) 2013 The IPython Development Team
6 #
7 # Distributed under the terms of the BSD License. The full license is in
8 # the file COPYING, distributed as part of this software.
9 #-----------------------------------------------------------------------------
10
11 #-----------------------------------------------------------------------------
12 # Imports
13 #-----------------------------------------------------------------------------
14
5
15 from .base import TestsBase
6 from .base import TestsBase
16
7
17 from ..convert import convert
8 from ..converter import convert
18 from ..reader import read, get_version
9 from ..reader import read, get_version
19 from ..current import current_nbformat
10 from .. import current_nbformat
20
11
21 #-----------------------------------------------------------------------------
22 # Classes and functions
23 #-----------------------------------------------------------------------------
24
12
25 class TestConvert(TestsBase):
13 class TestConvert(TestsBase):
26
14
27 def test_downgrade(self):
15 def test_downgrade_3_2(self):
28 """Do notebook downgrades work?"""
16 """Do notebook downgrades work?"""
29
17
30 # Open a version 3 notebook and attempt to downgrade it to version 2.
18 # Open a version 3 notebook and attempt to downgrade it to version 2.
@@ -37,7 +25,7 b' class TestConvert(TestsBase):'
37 self.assertEqual(major, 2)
25 self.assertEqual(major, 2)
38
26
39
27
40 def test_upgrade(self):
28 def test_upgrade_2_3(self):
41 """Do notebook upgrades work?"""
29 """Do notebook upgrades work?"""
42
30
43 # Open a version 2 notebook and attempt to upgrade it to version 3.
31 # Open a version 2 notebook and attempt to upgrade it to version 3.
@@ -1,24 +1,13 b''
1 """Test Notebook signing"""
1 """Test Notebook signing"""
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2014, The IPython Development Team
4 #
5 # Distributed under the terms of the BSD License. The full license is in
6 # the file COPYING, distributed as part of this software.
7 #-----------------------------------------------------------------------------
8
2
9 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
10 # Imports
4 # Distributed under the terms of the Modified BSD License.
11 #-----------------------------------------------------------------------------
12
5
13 from .. import sign
14 from .base import TestsBase
6 from .base import TestsBase
15
7
16 from ..current import read
8 from IPython.nbformat import read, sign
17 from IPython.core.getipython import get_ipython
9 from IPython.core.getipython import get_ipython
18
10
19 #-----------------------------------------------------------------------------
20 # Classes and functions
21 #-----------------------------------------------------------------------------
22
11
23 class TestNotary(TestsBase):
12 class TestNotary(TestsBase):
24
13
@@ -28,7 +17,9 b' class TestNotary(TestsBase):'
28 profile_dir=get_ipython().profile_dir
17 profile_dir=get_ipython().profile_dir
29 )
18 )
30 with self.fopen(u'test3.ipynb', u'r') as f:
19 with self.fopen(u'test3.ipynb', u'r') as f:
31 self.nb = read(f, u'json')
20 self.nb = read(f, as_version=4)
21 with self.fopen(u'test3.ipynb', u'r') as f:
22 self.nb3 = read(f, as_version=3)
32
23
33 def test_algorithms(self):
24 def test_algorithms(self):
34 last_sig = ''
25 last_sig = ''
@@ -80,7 +71,7 b' class TestNotary(TestsBase):'
80 self.assertTrue(check_signature(nb))
71 self.assertTrue(check_signature(nb))
81
72
82 def test_mark_cells_untrusted(self):
73 def test_mark_cells_untrusted(self):
83 cells = self.nb.worksheets[0].cells
74 cells = self.nb.cells
84 self.notary.mark_cells(self.nb, False)
75 self.notary.mark_cells(self.nb, False)
85 for cell in cells:
76 for cell in cells:
86 self.assertNotIn('trusted', cell)
77 self.assertNotIn('trusted', cell)
@@ -91,7 +82,7 b' class TestNotary(TestsBase):'
91 self.assertNotIn('trusted', cell.metadata)
82 self.assertNotIn('trusted', cell.metadata)
92
83
93 def test_mark_cells_trusted(self):
84 def test_mark_cells_trusted(self):
94 cells = self.nb.worksheets[0].cells
85 cells = self.nb.cells
95 self.notary.mark_cells(self.nb, True)
86 self.notary.mark_cells(self.nb, True)
96 for cell in cells:
87 for cell in cells:
97 self.assertNotIn('trusted', cell)
88 self.assertNotIn('trusted', cell)
@@ -105,18 +96,55 b' class TestNotary(TestsBase):'
105 nb = self.nb
96 nb = self.nb
106 self.notary.mark_cells(nb, True)
97 self.notary.mark_cells(nb, True)
107 self.assertTrue(self.notary.check_cells(nb))
98 self.assertTrue(self.notary.check_cells(nb))
108 for cell in nb.worksheets[0].cells:
99 for cell in nb.cells:
109 self.assertNotIn('trusted', cell)
100 self.assertNotIn('trusted', cell)
110 self.notary.mark_cells(nb, False)
101 self.notary.mark_cells(nb, False)
111 self.assertFalse(self.notary.check_cells(nb))
102 self.assertFalse(self.notary.check_cells(nb))
112 for cell in nb.worksheets[0].cells:
103 for cell in nb.cells:
113 self.assertNotIn('trusted', cell)
104 self.assertNotIn('trusted', cell)
114
105
115 def test_trust_no_output(self):
106 def test_trust_no_output(self):
116 nb = self.nb
107 nb = self.nb
117 self.notary.mark_cells(nb, False)
108 self.notary.mark_cells(nb, False)
118 for cell in nb.worksheets[0].cells:
109 for cell in nb.cells:
119 if cell.cell_type == 'code':
110 if cell.cell_type == 'code':
120 cell.outputs = []
111 cell.outputs = []
121 self.assertTrue(self.notary.check_cells(nb))
112 self.assertTrue(self.notary.check_cells(nb))
113
114 def test_mark_cells_untrusted_v3(self):
115 nb = self.nb3
116 cells = nb.worksheets[0].cells
117 self.notary.mark_cells(nb, False)
118 for cell in cells:
119 self.assertNotIn('trusted', cell)
120 if cell.cell_type == 'code':
121 self.assertIn('trusted', cell.metadata)
122 self.assertFalse(cell.metadata.trusted)
123 else:
124 self.assertNotIn('trusted', cell.metadata)
125
126 def test_mark_cells_trusted_v3(self):
127 nb = self.nb3
128 cells = nb.worksheets[0].cells
129 self.notary.mark_cells(nb, True)
130 for cell in cells:
131 self.assertNotIn('trusted', cell)
132 if cell.cell_type == 'code':
133 self.assertIn('trusted', cell.metadata)
134 self.assertTrue(cell.metadata.trusted)
135 else:
136 self.assertNotIn('trusted', cell.metadata)
137
138 def test_check_cells_v3(self):
139 nb = self.nb3
140 cells = nb.worksheets[0].cells
141 self.notary.mark_cells(nb, True)
142 self.assertTrue(self.notary.check_cells(nb))
143 for cell in cells:
144 self.assertNotIn('trusted', cell)
145 self.notary.mark_cells(nb, False)
146 self.assertFalse(self.notary.check_cells(nb))
147 for cell in cells:
148 self.assertNotIn('trusted', cell)
149
122
150
@@ -7,48 +7,52 b' import os'
7
7
8 from .base import TestsBase
8 from .base import TestsBase
9 from jsonschema import ValidationError
9 from jsonschema import ValidationError
10 from ..current import read
10 from IPython.nbformat import read
11 from ..validator import isvalid, validate
11 from ..validator import isvalid, validate
12
12
13
13
14 #-----------------------------------------------------------------------------
15 # Classes and functions
16 #-----------------------------------------------------------------------------
17
18 class TestValidator(TestsBase):
14 class TestValidator(TestsBase):
19
15
20 def test_nb2(self):
16 def test_nb2(self):
21 """Test that a v2 notebook converted to v3 passes validation"""
17 """Test that a v2 notebook converted to current passes validation"""
22 with self.fopen(u'test2.ipynb', u'r') as f:
18 with self.fopen(u'test2.ipynb', u'r') as f:
23 nb = read(f, u'json')
19 nb = read(f, as_version=4)
24 validate(nb)
20 validate(nb)
25 self.assertEqual(isvalid(nb), True)
21 self.assertEqual(isvalid(nb), True)
26
22
27 def test_nb3(self):
23 def test_nb3(self):
28 """Test that a v3 notebook passes validation"""
24 """Test that a v3 notebook passes validation"""
29 with self.fopen(u'test3.ipynb', u'r') as f:
25 with self.fopen(u'test3.ipynb', u'r') as f:
30 nb = read(f, u'json')
26 nb = read(f, as_version=4)
27 validate(nb)
28 self.assertEqual(isvalid(nb), True)
29
30 def test_nb4(self):
31 """Test that a v4 notebook passes validation"""
32 with self.fopen(u'test4.ipynb', u'r') as f:
33 nb = read(f, as_version=4)
31 validate(nb)
34 validate(nb)
32 self.assertEqual(isvalid(nb), True)
35 self.assertEqual(isvalid(nb), True)
33
36
34 def test_invalid(self):
37 def test_invalid(self):
35 """Test than an invalid notebook does not pass validation"""
38 """Test than an invalid notebook does not pass validation"""
36 # this notebook has a few different errors:
39 # this notebook has a few different errors:
37 # - the name is an integer, rather than a string
38 # - one cell is missing its source
40 # - one cell is missing its source
39 # - one cell has an invalid level
41 # - invalid cell type
42 # - invalid output_type
40 with self.fopen(u'invalid.ipynb', u'r') as f:
43 with self.fopen(u'invalid.ipynb', u'r') as f:
41 nb = read(f, u'json')
44 nb = read(f, as_version=4)
42 with self.assertRaises(ValidationError):
45 with self.assertRaises(ValidationError):
43 validate(nb)
46 validate(nb)
44 self.assertEqual(isvalid(nb), False)
47 self.assertEqual(isvalid(nb), False)
45
48
46 def test_future(self):
49 def test_future(self):
47 """Test than a notebook from the future with extra keys passes validation"""
50 """Test than a notebook from the future with extra keys passes validation"""
48 with self.fopen(u'test3plus.ipynb', u'r') as f:
51 with self.fopen(u'test4plus.ipynb', u'r') as f:
49 nb = read(f)
52 nb = read(f, as_version=4)
50 with self.assertRaises(ValidationError):
53 with self.assertRaises(ValidationError):
51 validate(nb, version=3)
54 validate(nb, version=4)
52
55
53 self.assertEqual(isvalid(nb, version=3), False)
56 self.assertEqual(isvalid(nb, version=4), False)
54 self.assertEqual(isvalid(nb), True)
57 self.assertEqual(isvalid(nb), True)
58
@@ -54,6 +54,10 b' def new_output(output_type, output_text=None, output_png=None,'
54 if not isinstance(metadata, dict):
54 if not isinstance(metadata, dict):
55 raise TypeError("metadata must be dict")
55 raise TypeError("metadata must be dict")
56
56
57
58 if output_type in {u'pyout', 'display_data'}:
59 output.metadata = metadata
60
57 if output_type != 'pyerr':
61 if output_type != 'pyerr':
58 if output_text is not None:
62 if output_text is not None:
59 output.text = cast_unicode(output_text)
63 output.text = cast_unicode(output_text)
@@ -86,8 +90,6 b' def new_output(output_type, output_text=None, output_png=None,'
86
90
87 if output_type == u'stream':
91 if output_type == u'stream':
88 output.stream = 'stdout' if stream is None else cast_unicode(stream)
92 output.stream = 'stdout' if stream is None else cast_unicode(stream)
89 else:
90 output.metadata = metadata
91
93
92 return output
94 return output
93
95
@@ -295,7 +295,6 b''
295 "description": "Type of cell output.",
295 "description": "Type of cell output.",
296 "enum": ["pyerr"]
296 "enum": ["pyerr"]
297 },
297 },
298 "metadata": {"$ref": "#/definitions/misc/output_metadata"},
299 "ename": {
298 "ename": {
300 "description": "The name of the error.",
299 "description": "The name of the error.",
301 "type": "string"
300 "type": "string"
@@ -43,7 +43,8 b' def _relax_additional_properties(obj):'
43 def get_validator(version=None, version_minor=None):
43 def get_validator(version=None, version_minor=None):
44 """Load the JSON schema into a Validator"""
44 """Load the JSON schema into a Validator"""
45 if version is None:
45 if version is None:
46 from .current import nbformat as version
46 from .. import current_nbformat
47 version = current_nbformat
47
48
48 v = import_item("IPython.nbformat.v%s" % version)
49 v = import_item("IPython.nbformat.v%s" % version)
49 current_minor = v.nbformat_minor
50 current_minor = v.nbformat_minor
@@ -1,23 +1,11 b''
1 """Test help output of various IPython entry points"""
1 """Test help output of various IPython entry points"""
2
2
3 #-----------------------------------------------------------------------------
3 # Copyright (c) IPython Development Team.
4 # Copyright (C) 2013 The IPython Development Team
4 # Distributed under the terms of the Modified BSD License.
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
5
14 import IPython.testing.tools as tt
6 import IPython.testing.tools as tt
15 from IPython.testing.decorators import skip_without
7 from IPython.testing.decorators import skip_without
16
8
17 #-----------------------------------------------------------------------------
18 # Tests
19 #-----------------------------------------------------------------------------
20
21
9
22 def test_ipython_help():
10 def test_ipython_help():
23 tt.help_all_output_test()
11 tt.help_all_output_test()
@@ -37,6 +25,6 b' def test_locate_help():'
37 def test_locate_profile_help():
25 def test_locate_profile_help():
38 tt.help_all_output_test("locate profile")
26 tt.help_all_output_test("locate profile")
39
27
40 @skip_without('IPython.nbformat.current') # Requires jsonschema to be installed
28 @skip_without('IPython.nbformat') # Requires jsonschema to be installed
41 def test_trust_help():
29 def test_trust_help():
42 tt.help_all_output_test("trust")
30 tt.help_all_output_test("trust")
@@ -6,6 +6,7 b' The IPython notebook'
6 :maxdepth: 2
6 :maxdepth: 2
7
7
8 notebook
8 notebook
9 nbformat
9 nbconvert
10 nbconvert
10 public_server
11 public_server
11 security
12 security
@@ -199,6 +199,7 b' def find_package_data():'
199 'IPython.nbformat' : [
199 'IPython.nbformat' : [
200 'tests/*.ipynb',
200 'tests/*.ipynb',
201 'v3/nbformat.v3.schema.json',
201 'v3/nbformat.v3.schema.json',
202 'v4/nbformat.v4.schema.json',
202 ]
203 ]
203 }
204 }
204
205
@@ -1,164 +0,0 b''
1 {
2 "metadata": {
3 "cell_tags": [
4 [
5 "<None>",
6 null
7 ]
8 ],
9 "name": ""
10 },
11 "nbformat": 3,
12 "nbformat_minor": 5,
13 "extra": 5,
14 "worksheets": [
15 {
16 "cells": [
17 {
18 "cell_type": "heading",
19 "level": 1,
20 "metadata": {},
21 "source": [
22 "nbconvert latex test"
23 ]
24 },
25 {
26 "cell_type": "markdown",
27 "extra_key": ["list"],
28 "metadata": {},
29 "source": [
30 "**Lorem ipsum** dolor sit amet, consectetur adipiscing elit. Nunc luctus bibendum felis dictum sodales. Ut suscipit, orci ut interdum imperdiet, purus ligula mollis *justo*, non malesuada nisl augue eget lorem. Donec bibendum, erat sit amet porttitor aliquam, urna lorem ornare libero, in vehicula diam diam ut ante. Nam non urna rhoncus, accumsan elit sit amet, mollis tellus. Vestibulum nec tellus metus. Vestibulum tempor, ligula et vehicula rhoncus, sapien turpis faucibus lorem, id dapibus turpis mauris ac orci. Sed volutpat vestibulum venenatis."
31 ]
32 },
33 {
34 "cell_type": "heading",
35 "level": 2,
36 "metadata": {},
37 "another_attr": {},
38 "source": [
39 "Printed Using Python"
40 ]
41 },
42 {
43 "cell_type": "code",
44 "collapsed": false,
45 "key": "value",
46 "input": [
47 "print(\"hello\")"
48 ],
49 "language": "python",
50 "metadata": {},
51 "outputs": [
52 {
53 "output_type": "stream",
54 "meta": 5,
55 "stream": "stdout",
56 "text": [
57 "hello\n"
58 ]
59 }
60 ],
61 "prompt_number": 1
62 },
63 {
64 "cell_type": "heading",
65 "level": 2,
66 "metadata": {},
67 "source": [
68 "Pyout"
69 ]
70 },
71 {
72 "cell_type": "code",
73 "collapsed": false,
74 "input": [
75 "from IPython.display import HTML\n",
76 "HTML(\"\"\"\n",
77 "<script>\n",
78 "console.log(\"hello\");\n",
79 "</script>\n",
80 "<b>HTML</b>\n",
81 "\"\"\")"
82 ],
83 "language": "python",
84 "metadata": {},
85 "outputs": [
86 {
87 "html": [
88 "\n",
89 "<script>\n",
90 "console.log(\"hello\");\n",
91 "</script>\n",
92 "<b>HTML</b>\n"
93 ],
94 "metadata": {},
95 "output_type": "pyout",
96 "key": "value",
97 "prompt_number": 3,
98 "text": [
99 "<IPython.core.display.HTML at 0x1112757d0>"
100 ]
101 }
102 ],
103 "prompt_number": 3
104 },
105 {
106 "cell_type": "code",
107 "collapsed": false,
108 "input": [
109 "%%javascript\n",
110 "console.log(\"hi\");"
111 ],
112 "language": "python",
113 "metadata": {},
114 "outputs": [
115 {
116 "javascript": [
117 "console.log(\"hi\");"
118 ],
119 "metadata": {},
120 "output_type": "display_data",
121 "text": [
122 "<IPython.core.display.Javascript at 0x1112b4b50>"
123 ]
124 }
125 ],
126 "prompt_number": 7
127 },
128 {
129 "cell_type": "heading",
130 "level": 3,
131 "metadata": {},
132 "source": [
133 "Image"
134 ]
135 },
136 {
137 "cell_type": "code",
138 "collapsed": false,
139 "input": [
140 "from IPython.display import Image\n",
141 "Image(\"http://ipython.org/_static/IPy_header.png\")"
142 ],
143 "language": "python",
144 "metadata": {},
145 "outputs": [
146 {
147 "metadata": {},
148 "output_type": "pyout",
149 "more": "data",
150 "png": "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\n",
151 "prompt_number": 6,
152 "text": [
153 "<IPython.core.display.Image at 0x111275490>"
154 ]
155 }
156 ],
157 "prompt_number": 6
158 }
159 ],
160 "keys": ["value", "s"],
161 "metadata": {}
162 }
163 ]
164 } No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now