<?xml version="1.0" encoding="UTF-8"?>
<Worksheet><Version major="6" minor="1"/><View-Properties><Hide name="Section Range"/><Hide name="Group Range"/><Zoom percentage="100"/></View-Properties><Styles><Layout alignment="left" bullet="none" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Heading 3" rightmargin="0.0" spaceabove="0.0" spacebelow="0.0"/><Layout alignment="centred" bullet="none" linespacing="0.0" name="Author" spaceabove="8.0" spacebelow="8.0"/><Layout alignment="left" bullet="none" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Heading 2" rightmargin="0.0" spaceabove="7.9992003" spacebelow="2.0016"/><Layout alignment="left" bullet="none" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Heading 1" rightmargin="0.0" spaceabove="7.9992003" spacebelow="4.0032"/><Layout alignment="left" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Normal" rightmargin="0.0" spaceabove="0.0" spacebelow="0.0"/><Layout alignment="centred" bullet="none" firstindent="0.0" leftmargin="0.0" linebreak="space" linespacing="0.0" name="Title" rightmargin="0.0" spaceabove="12.0024" spacebelow="12.0024"/><Layout alignment="left" bullet="dot" linespacing="0.0" name="Bullet Item" spaceabove="3.0" spacebelow="3.0"/><Font background="[0,0,0]" bold="true" executable="true" family="Monospaced" foreground="[255,0,0]" name="Maple Input" opaque="false" size="12"/><Font background="[0,0,0]" bold="false" executable="false" family="Times New Roman" foreground="[0,0,0]" italic="false" name="Text" opaque="false" size="12" subscript="false" superscript="false" underline="false"/><Font background="[0,0,0]" bold="false" family="Times New Roman" foreground="[0,0,0]" italic="false" name="Bullet Item" opaque="false" size="12" underline="false"/><Font background="[0,0,0]" bold="true" family="Arial" foreground="[0,0,0]" italic="true" name="Heading 3" opaque="false" size="14" subscript="false" superscript="false" underline="false"/><Font background="[0,0,0]" executable="false" family="Times New Roman" foreground="[0,0,0]" name="2D Math" opaque="false" size="12"/><Font background="[0,0,0]" bold="true" family="Arial" foreground="[0,0,0]" italic="false" name="Heading 2" opaque="false" size="16" subscript="false" superscript="false" underline="false"/><Font background="[0,0,0]" bold="true" family="Arial" foreground="[0,0,0]" italic="false" name="Heading 1" opaque="false" size="18" subscript="false" superscript="false" underline="false"/><Font background="[0,0,0]" family="Times New Roman" name="Author" opaque="false" size="12"/><Font background="[0,0,0]" bold="true" family="Arial" foreground="[0,0,0]" italic="false" name="Title" opaque="false" size="36" subscript="false" superscript="false" underline="false"/><Font background="[0,0,0]" bold="false" family="Times New Roman" foreground="[0,0,0]" italic="false" name="Normal" opaque="false" size="12" underline="false"/></Styles><Group><Input><Text-field layout="Title" style="Title"><Image height="78" width="800">TUZOV3RLVWI8b2I8Uj1NRExDZE5WWlpKOnROPkg6eFhWRXJwczo7Qk5TRE9FVGxNWGxnd2dpVzttRFtVVVVXVXNLaXRVZl1XZnZfaXZtaXhvWUtFVmNzSXl1eXZheXZVSXZfaW9peG9PV2tneHdpeXdPdmVDSHdnSXhpSXhteXFBWXNdSXdnWXRVaXVJWHBDSUZpU0lhQkFBc2E7R2JZeXZjaXhxeXhlWXdleXVZeXVXZE1XVHVVWXV5eXl5QTs6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjpaamlmRHFFdGtdYE5cXEBOZFxcUWdxeEhgandoU1dEUVZ5UHhQTEFJWFVgd3l5eVNVdW5gcltETlpdV21ValB1SlpdWV9sU0xxcVdpb1N4d3d0TEVRbEBVTkdpT0NAWHlRalhMWWJJdk48eHdhTG5BdD11T1pkUW5BdEU8U0lkUW5RSkxZUklkcTpgeEpZcnlxSkJoeU5Gdkw/Xl5Zb09BW3lZZWxvZmlHYnQ/d1t3W1BoZEs/Z1NPXkRHcExZZUpwXXQ/ZmpIb1xcSV86eW87SF1cXGBcXDpHb0RGXWBocUVodD13W0ZfYWxTPXdVVG9UdE9IUHdDYm9yWVt3Oj1FcFlkUllyWU1DaEtkRT9CRG1pZEtHPVFzQ19ZUm1IblFCTFlyP1FlRV9YX2tyaWdlOltpQlljZl9ERGFHZVNzXFxlVFBPYl93WXJ3c1hpcmRJdmlHYk53R107VFllVEttZ3l3dkpHQnN5Q3ldVmxtRmV5RVF3Y1g9amp5eDpgc1FNUF5cXFlQaG9fVGs+eE1zbXRzSVBNaEttWUx3TVh3SVdYcU14cVBJVWtFUVQ/bW9EaHRIRW9fbFlAbVFIUXBaRHlMVXJZSHBuPHlSdXRuSFV2PGxweEtZUFd3SVhSX3BgSWBwWGZXT3l5PmVNeV9KV3U9cWFSPnBwVnhPXmZ1bnI/R2BIdl5RaWFddnV1b2NKcHdVUWRUZ2RgX21leF1UdmZcXHhmcmhkYlh2cEllX0hzW0lpSD5uVW9udkBiS3BpWkh0WGBpYmhmS09gSkZkUFBrSXF2eV5xPD9tQHZ1dkFba2BmRGhia1lkTnF4al9jPl9mT2Z2X3dkeF5fRT91WVh5UUBvbEZxWUlmO19lXUl5UFZxbm9zZlB5SkFePWFzdXFbamBaUj9rRV55akh0SFFnT0h4U25cXHdZb0loYFRZXFxGZ2BSeGBJcVtWd3E6QF1UeXliUXh2QF1rPmtpdmRhWVxcdWlcXGRXaXJuW1BxclRncFBZYnhedHZGZmtXWmJpaGxZYT5eYktAd1R3c1Fodk95YkA/XWdxaHdvbW5nXz5vZz0+d3BHYXJBY11oaWJBeVhAZUxvZ1FuaGx5a0Q/czxfY1xcPmJAUXV2QV5reG1ecHBBWHZqVlpzRl5BRm9eX25WVmZsaXhyaWZoYXFpP2JISVxcSmZfXU9dc15gbHlzc0FzcF9iPUlaXWFrZFBtSm5pQXZeUG5hTkF3OkdpPlZxbWZ2Ukl1eUZfW05tcFFqYz9wSXFeUFdqaUZkVVlyYz5nbFBxaFBbQj9qTE5xS0F3eXhuVmhxXFxhallRXlpGVlF4az9lO19mQFViSVNzPz9UPGFCdz1mS11VeVl5W29SQU15Uj1Id2l3RVVIZm1SUFN0eV1Uc1N0YkFIeFN1WU1zXnlHS1V1PUlCPVF4ZW1VQT1ycndJO2FJWD1CSj9iXnNzW19UWEVZVENlRWt1R2dDTmdlRUtZOnl4RUtCTFdibXVCSGt2ak9ndmFjSV9XPV9kR2t0UmVnWXdyXVdGUT95VEtCQlV3SVtIVFlyQnlHanlGXFxXYndndnddU3hhd2FhV3M7eUF3VENBU155eGQ/WGQ9c0JneVJhRFc9RGpzVDo9aFxcS2dtTUdbYXZcXEtkXXNUSkVjdltkVjtmdmNoO3dTOl9Ea1l1XVF3T0NkTztzZz15b2V5dFNHYGtJbXNGeW9nXj94RU9CTENGVmlESWdJQEd5XW90XmlyUDtISz9oWk9zamdTXFxvSD9FVVN1REdNVUF1RkpJSGlfRktTV1V3UlRbaG89U3VjY147SXNfVlRVRT1JQ29TSXN3Q1dxUlpRRzxfaVVhY3JDZWhPY2FJUld1c3BxUmZZVEBjY2ZNdWhzeUNXclltSVBLSWJRaGRDZWhxeFxcc3Q/XURHXUVxTUlGWWZXXXJnVUNicXZJR1Nnb2ZMV2dgYUhKS2RsdUVxRWV1PWl4a3dRU3RyU1d0V2djZ3dKU0lHa3Veb3hnS1Z5UVdaRXReZ0JlS0daS3hjZWQ9SWRUT2hKRWZSW3hyTUJrS2debUdKXUhjW3RyT1Q6X1I/ZUZkX0ZWQ1haQ0Q/UUNxU1hdWWV0R0Y8RXVRZVVmY0NMTWhqR3ZWS3NfU1RrVXdeXUNFVUVsW2Y8P2hORXdkb0g/TVdmXUZiZXNQS1Vda2dIXWJTRVM7UVZWP2hIcWRUPWNlP2JwX2g9R0d1cUdEW3lAU1U9SUZLRXhFZVVXQWhOTVhed2RSWUZJTWV2S2VIWVdTc0NsW0hHYXVbQUVaaVJfaVRKVURTXVlja1hzb1Y+XUdCcWJAO1ZNPURsdVZIZ1Z1UWVEcXhMVUVdXVdTQVJfb0I/b3hMZ3I9PXZxa1I/TWNQQUVHXVdCS1ZQW0hWT0k+SXJFdUJrVWNxU2NrQ3dwc0ZvX1JjP2VCW2hoQ1hZU3JGQ2hWQVN0W1VVV1dzXWNlWUJoeUQ+YVVUTVdaO3ZEb1I8TWlnUUR1X1R0Q1V1UWVUcVhMT0k+UVZfQ2lJXXdfQ3J1RUhvc1J3b0ZmP0VjUWlKP2JoPHJUdVhbWG0+UU4/WXROZHBQUU1TeFVNPExxPXFASU5CQUtFVEpCaHhTdExzRXE6XFxWbVlNY0VKdkxNYFxcam9BV0tsdkxgb1RFeGJxUmBgdVJxSzs9UFg8TEF1c0NoTz9AbU5FamVhUF1JU1docEB5V2xcXFdjPXk8UWxQWEpRdVN3bFc9eHRZeXZKSE9UdEs7VFc+bE9JRE9EVEpaeU5vVVBSTHhIbHdQZWxLeFQ7dG9SRXZcXEFsY11rYnBwZmB5b2x5dlB2T01reERLPl11XFxFVkNdTkFhbkFZYz1GXktfdWRnZFtRXlZpXkRyPlt0Uj1IXFxhR18/R1RbcnRTcnVbWEJ1R0RzVUthZz9RVUVHRUtDaWdjR01lWW9HQjxVUkJJYltlYnZZRkFLYkd5R0s9Q01RQ1FdQ15bVWtVVEZjWFZFaD1dZzxbVkRvQkFJZ095WENnc1FzZGBDRmM9dWpRSEtdWWM7eE9PaUBZeGxPRlhFYnhPR2VDczxraGFJUlZJZ09tcz1lVE9JeVB5cmZ5QnRxdFZ1eVJFeTpvclBjZVxcSWdxa2JWTVVaQVg+c0hzVXVPa1lxQWdDPXN5b1lBc3ZgS0NoQVheV1JdX3h2Y0Zfa1JnQWNeSWNQW1NJX0RbVWY9TWVyb2ZjUUdvWUJmY2NhW1RpRVR2YWU7PUhHY3RhcXZ1V0hkO0liQWlKRVlkeXRHP2hCb3JkVVRYV0M7ZWJjaXNMW1V4WURDW2drUXJITWdIcWVibXJpa3ZqP0hyU2lQeXJja3hrQ3dRQURDb0llRXZiVWJHQWJvUWhYRWhbO2RcXEtISG1iX09GdFd1X3liX1VjUk90bndiUVVIakV1TD1VcF9SYj1VWUFnVU1FPmdDQWdDaXlTRW9zRVFVR3FkV01XcT1jP0VyS01XSUdGd09DZUd3Xz9jQFlCTT1zYFFlcz9VYEd2RElHdV1EaF9VXFxhRUNRQ2tpZ2BLWV5JZDxVckZTR2RpZENRZD93dmpzZ2pvY2Bhdj9BQlVjQ3FrRGJnVVFtWWRXVHlVSElFSV4/dk89eHJJWUBfSVhLeHlleTpXeV1ZUnJ1eERpR2lTdj91aUhHYlZRbDpES1tIbXJwUEhQcV5QbEVcXGtBTWt2bUxMeWxGQW9rbGpjZXY9bHFpPFlXdFJMZXdxSVFQXW51VGpTcXZvXXhndHI6YFREZW9zYHFzWG9VdHNePFFWQUtkPWxIRXdSUU9WWXFFeVRvYFk6YVlOUEtoXFxWPkFzTlF4O1R4cmRXXllKXnRqYVxcdkhkbmxVa1Jla29ZSnZYT1Zlc09xbFVNTkBtUG5VUG9YbVRAanRtVWRwS29IeGhtdUQ9UUhld2tcXG5CbE9odXFXWG93eXM8XFxWUGRrWkFKZ0VSb2BSQGV2W2V2cFRxYGFTeDxOVUF2eVVyYV1udnRSaUh1QlRRSVRzXFxxVlxceUxsXXJhWHRcXEBQQ0hTQHRyO1xcWG1EUztYbUZwVlJ5WHVIaklNS0JgbVppdlc9TkhUU0FcXHNycHRnTW1JQU5xZXVZQHFKTU9GaHJ4RUxpXXZvbXJQQGtnXVRFTVNORVhyZWxteXJveGtVXFxZeU1sbT1LYEF2dmFYV21LUXFtQTxRVElVXklRaG13XklZSFFxXlxcc1dsbEVdc2tscz1RWXdBUnRwVVBIVldpbj5US3llcWBETGtZUEQ9Vll4T1VpdTxRVG89dT1QVWNZWEx5a0VNbUJIWXd1T1Nkc211dV9kUm1dV2xwTElcXHhLbHF5QEteQU86SUpcXGFvO1lzZEh4UkhwT0B5REBMP0lwTHhyZFVwX0h2Y3B2Z111RVFWS1h3dmRucGBWTnFWVkB0W2xMX2lvO3FPSVVOd0xTZmlKOm10PnlWVHFOZ01Wb2FvUF1STmlWRFFPYEBWRGlzZEh5d3RZO0BWZnRMcVlsc3RyRTx2aG1yQmltVU1yPkVrSkF1R3h2WWlZSm1XeHhZcWRqR3hLbF1UQFFQVllPWWBMSmBtYGFqTlxcTUJNVlFteXNMTkRZc3E8b3BZeVNEbWBBdlBAcUJIbFBpT1xcQXg8cW9cXEBZZVhyU0hQUkBWZVlWR0FTcnhRWllQR3R0c1BrXWVMRWhXbzxQR0FQP1F4WkxYWDx1Y01TXFxsSnlkU1NNd0dAa1FMdmpBTVdUeVV0b3hVTGtVUFhUdTxQUVxcaHNhUGtkUEtOaHVIZGtBdHVDUVBaUU1LRFN2UVZQWXlwTFJUeHlNVFBWTVVVaHFzbW1EcG5jWWxYPU5xbHFreFJwZFBPZWtSeE1wQGtTbFVdSFc7eHQ/PVNfTG09QXRuYExxVVFFRVZCQVdCVW5uPXRCTFh4cHRGYE5TQVRkVU5HSFRFPFdOSU5QeFdOSVJHZXdKVE53SHU9TVlWQHVFQEs8TU1fZVNHRWtfRFBAYVZAbWxAPUxcXEV1Q1B2Y3l3U3BrYUB1W3RRaERwPGVTQEF2bUBVXFxNdj1BUVpEVztNTXdVa1E9bT1hVE1BWV1Mb3V1UzpNTlxceVBzXFxRWG1QVkl3dnFKb1BNVElwckFzXlFSdmxzU110TmRLQ0VsP3hUd21uW3Byal1XTXhLT0ROSUlMXkBzbjxZZkVrWEhRTmRRTXRXTGFQTVFMcVVUP015WnRXVGFSQ1Vsa0BYO0BtV2RLP21uVkRsRkB4dnRMVlFRc0ltXlRXczxvWD1LYUV1RWhZRUx0YF1RckB5VEhYUnR4Qlh1dkRyWmR0Xk1uVkhYSWFSeHFMS0xTR0FTTUh3XUBqZHlyTlRNPT1zZV1yYF1vRzxLXFw9VlBgWUtEalh1VHVJakVAd0NRU3hkTV5Ad1BQUz1Nc2I9az5MT1tcXG87dHNtXVVDSUxkRVZqPFM7UFRFaU5VTVZNbW9QdUpHTFRIVE5HcFhLUEtnRHBKbFVUSEtzdW88UGNKbl9jeHBARndhZ1pOWV9XcGVNYHFBV2ddaFxcZklzQWBiWl5hdGl0dXdgPkFpYXloW1ByRVFpZ3BiTU93eXZhSnZ4OkhnYllnO1htPE9yTW9nZFB3XFw+Xj8/a05GYVZYcUdQXmR5WndGcldHeEtuW2tmZ0w+YEdZblBZa2R3YktxYllYcHBoaE9Hcz55W1tGc3VWXUF2Okd1VktHWD9ydG1iVT1VQXlCWFFWSU93RHFFS0lFc29lOmFkXWtYSmF2UkdkZFtCd01jdUVZXFxlRURleF1bZHhPZV1BdVJJZEJLdlNbRD5DWGdBVkhdQndVVUdzQllpeEJ5ZlZ3dnJrU2FdQm1HV2djZnFfaWw7aGdpZzxBUnVhckh1aE5RZHFrSGtLV3FBZHBFY0dvR0NNSV5pd2FXY1d5RlNtU2xxc0lfV21nR2NxZVZpc21xYm9XaFlXR2RXU0ZHQ253dmtPSD9rRlBDc2pvaGFhRG95Z0I7Y2VzUlI9SFBBY0FbaXZhck5nckdReWY7Y2VbY1NhYj5vRjxlWEpdYkE/cmdJVUpLZXRtc2NxQ3FFVUxtVTxNZmVRd3J5dEtzWHRzdmd3ZlI9c3NlZV1lVnI9aVhnVHVzUkVLSXJhd1ZhZXNvRFtdeXFBZ1Q9VkU7WHdnVFg7Q3NpY21zaFpJeWhddGY7RD5hZ1lrU1o7Y0VlZU9VYnBnQktdQ15jY2g9WFtXY3c/VEtdRF9rd1pjcl5hSU1haXZdZ0M/dVJbaUFlR249Z1dJUkRZeGFBZ0x5aVVbY29zZlRNc2BXSEVDZVdpaFpTaVtTU0g/dkRdQ0NTeUpTZUxhd3A9ZEJfeE9PeEtxZ0BjeV4/YmJfd0pTQ2BVWVRbYk5FR2RdSFppSU9BYlZPckplRWNLSWo/Rm5hV2dBZWxTQ0FfV0tddFxcQVVBcVNNTURoU1ZSZ2VwP0JGTXVda1JEa3ZPS3dgXWl5XVNzQXhuVXQ+U2ZpO0lXdXV1R2V2PXJoV2RAcWdnWUZIdWNyPWZmb3ZMUUJfW2U+PWllQXdqQWRcXGloRFV0T1NIRmVXXndpQWVXbk1DY3NYc21oXW94Qz9nXz9mWWdybnNTdmd1dU1iW0lmP0NmYG1SUEV2WXVzbDtYUT1TcW1EUkFzdWN0UEd2c2d4SGdCS3VpXFw7RnZdR0xBRF5bQ29NRT4/U09XVWlnVEtVWVRZRFRjSVZDR3Q7YEZPXVVma1dWXkd3a2FXYHVma0tQWnQ/XFxEd15vT19cXF5pd0Bibl9tdk5eXT92S3FjYHZgdFZzPEB5Zk5fZWBcXER2c0ZnYGlZY0xIdHdfYkt3WmteaEtWbmhWZm1nXFxzSXdRUGZBR2BQbmh1aWtqd3c9YXRYUGJkd2VOQGpOV3VHYGFnaWJeVmlZZmVhUGlyP2c7X1s9T3I6eFxcdnFpPWlxWmlaVHZrQGFmWHZwZHFsU1dcXGlweWRhcllHXFxKRm09WV94Z2U/X1pCcWNESF9Od3JOWHhrUG49V1tsWW49YV89SFpbaW4/UG5BYXlUP3l4dmlpeGJoWHI7aWdkSGlvb1FdZURXZmJpRkBTeD1jdHZ3dVtRV0lpSV5zRV1XclBbRWJNdWdXUm5zQmRbeVJbZD9ZVT1NeWJjaGFkcVI9bG9NdndEU1dZUFd4UlxcPUxPZFdqPExJbXVMXXc8WE5BRVJPaHdLSEx4bUtmdFN4WVVmPEtFTXh4dExObFlLeHI+dVF0cFRWWVV0XFxtdWRUYVxcdF1lblpEUXBgWWtxU0lAb11xT3BgbG9dUEN4eHhBa3J4eF9Ec1RJbVFIU2F5VGhhUkVcXEpMdHB0cVJBdVF5WE9OZFV5VU47YXhbTVdzeHhOPXQ/PUpfeVU/UEs/UXg6SG5fWU5rPFNMSXlcXFVVRFlPaGh2Ok11Zm1Na0lPclVKcVhzbERyVUB3WXFRRWhMS0FrW1hua3F2X114Y1VLbD1UYUVuVUVOUG12SGlwVnBTSFl0Y1BRS3hUSVV3YFhYZUFxW2lYeWhxWGRXXXF1U2xrdVVOVFF3W2h5V2FsUkVTUWhLdWRNUHVSTkhRVlRwWjxWQUhuc0hsWXh2Xm1tVkhKdERZb1R3XWF0XFxYWF5ZeTxMakpga1ZAb110Uz1YSnFNUV1FcHFgc1ZJSl5wV3RQS2NMbWtkTklodVo9V1l5dmhUTnJwVFBpTXdUUWFxcVpFUm5YamU9bklgVXg9cFB1dHRdWF5Ad0dVS0x4als9cUpRblldVk1MVUZNcnFgd0lEc1hoUGNAUVxcQXlydFR1SE49SWtmZFVlcU9bbExxUXBIdHY9cUo+cU5ObVJVVUxeXXdSVExEQHFdYHNXaHhrVEs8aE5eZHJ4UW1rQVJGUXJWQXBKWFlybExXaFZLcXNgcHhSTFR3dVFqZHFmPHdSPWxPbXVfXU5cXGFYQ2lzZ21KdERYc2RVdFVMPFBrYFhwXjxVUlB1RVxcVHlAVUdES1hNS2xRTTpwdDxgbkh5dmc8a0V5bl5sVkZJUT5xUG51d0JleXJ1VG1IWW1YSl91ckRwS3FJUnBQTEx4UlZdSnRMU2t1anhtb2tFbHhNdXhBWE5ZV2NoUD1oUlh4VWpwdnFxbkdFbnY9WWpRclpUUF5lcFRxamFcXFBGRFludWNTUGRpZmxWZ1tqd1tId1xcal5fb3d1VlBkZmdfQ1ZnZFhuSGhoa1F3TVZzaGdaVHhvbFliaGBvakhxd19gZVhaXFw+d1hPbmVgbT9nb0xfd09uYEJ3YGFfdmZ5eVhHdUpHdWdmc29gbWdpdnRIbVheY1NwbVFhZlxcXl1ueWg9b1p4X3dQWG5PaXRyaWI6WHdZT2hwV3ldcWRsV3Z1YGNYPl1KZ3NtPnRkcXNzbl9GP2FuZnlOaFpLZ2dcXE5nRHlwO0FoOl9saEFzW3Z0REZcXE13aFxcZ3dCQWxbeWJNWF4/V2VdWWRFblp3aHk6UXc+YXV0QF9sT2w6PmhmZ2FveHVGUWJLbmJZSHBIUW9id15DX25XQHFEbnBjUXFFR2F3VlxcYEBybnBjbGhjaz5eWEdkTkBxZEF1W0ZmVUledV9cXDpgcWZ2cT9fc29HXFxVZ3VBQVxcQW5da1BsRk5kQkBzS1ZwZE50SF5nQWZvaXBkYUdkRUdsUHdiSlB0W09zUW5eVU5gbUZaWnZsbm9iPnlnTF53V1ltXFxWaGVWZU1HalBockpIZW5JYnBAeFxcd2VdWG9jYGBocGVgeHA6dnVYd2VNWWdbUHFUcG5pSGBvb1tKZ110P3NpQGBwdm9mSXRzblxcXklkYG92VmFnQXFsYUl4VkBdalZdZHZhUUZhbF9oYm93QU94RGBfYVlqSmhsb3FrV1lsSl5mQWZiaT5sTVBgUU5mW2dyWD5yQF9uSF9qX2FeVE52b3hpSlZyc15ldVBjb0BcXFFPW09fcEU+Z1lQbUBfbW9QXlVRX0JwZkVOY0hgak1uWmlZdG14YFZPZ3h2XFxmT3Fob2RAeW9XQW9ITmteV2JDWWRzT2hyeWdKbmRLdnFWWGJSQF1pPmpBSHlXXl1oP11meGdDSWNObl1Jb15sTndIRmY+QGdZQWtRVmNEQGlCP1xcVUdyVFZeaGZqRGlmZ155dEF5SXZcXFFgbXlWeGB2X0RRWlxcSHh0YF5RcV9zUW1AaGRDbnRUQGM9eGZnQGBVWW9cXFl4eGZwZ1lqSElgZGdnWW9fcWB0aEleV2BhPUdyQmhlVVZvUHdraHh5ZEdaU15ucD95Rl5tR2hodmhdVElePHFod3FeSEZcXHNRcFZHdG9vW0dhYklWXFxmQGZCeXdDP2pPd29HRlxcY0Z5cW5tbU5oZXduOndrZnhvYU9pcGhvOndfXnddR1hpQF54aVFlcUZpT25fZ0Feb1ZwVVluPE54RWdsP0lpZ2lgWlFobEd1V292QV94bmFcXFhOczp5Yl9QcHJYXkdpdjtGaHF4ZzxJdGVeZERGYWpIZlN2b1FZaT9XeFpQZGNJX05HbT1pWl5JdmA+ZFk/cD1xaG1QcD0+XU9gYklRd05nZWxRZD9WYllAaV9PYFxcSWJESWVaZnJtcGJsdmxaZlp5XnN2bnNuSWhtTmhbYXBqVmJtVmZVZlpbQXQ9YGZCZ3ZLZmdXeGtiP2Nmb2pkR3ZyaGlMZnZgWV9DX2RpcGdYd29DWHRzSGxcXG5dTlBabU9geVdcXGVeaFRfeERGbGhgW1BJXlpucFdwbURnWj1fY0dmY2NWdlpubkpZa1ZvZmdeaGxXdz5wYVxcYGxNcGZIUGpDUGo+R2ZuT2BUPmljdl1bZmpAdmt0UHJvbnltUFRnZGJQcD55TmRUbnBkb3JRbVRheTpEb0N4cmBpUD5RTGNoTkBEWERUcnlYeUldakc8dUVoTEBUdUE9bGV5T2ZcXFhyUHRacE9pbVlpcVFnUXJxWHZybFdxdXF0TFB2UXlwXXI/UVlOdXJgdU5XZVJgeHFeSGpGaXBnVVlYRHNBWXhOVHJtQE9KcVBJWW46ZW9GTVhZRXRjTFBScUxHSHdLbG5hVU1wSG9jTXdOPXlaVmZFXl5fSXFcXEZuQ19jVEhobldzVz9vTkBuYlBdXWhydkdicz9vcW5tQl9hW3h2bj5mY0BfRU9pPlhoTmZwdVZhQHhoTkljXm9ybUlxZmZvRl9tZkhjZ3lkZ05dX192OkhbcEBfUl5eS2BdZWFvTWlqUldcXFpPeWBoaEFwZVVwbUJoYEBAbVFgbltmaE1xYlRfb09maEVwaHRBbGA/bG5pZGJAdmh3YnFeeFZHY21vYG5odUphdmtOWkleYDxnZ2hIb0Q/YGhfbUlReUlIcUZWZ1txX1Rfbl1YYl5IXFxTZl5dbnRgd2ZXb19WbnZMSGZTbmJzWXl1aWBBUWdjcV1EPnNLQGZxZltDaGlTX1p2ZmZbSHRCUmxnRmA/c09TU3JxdmRBSUg/eHRtVV11V11HR0RhUmlTRj9NVHBLdm9raGJZRj5RaGhLVU4/RHk9VmZ3dj1FVkdXaXZvZUtfdUxhZ0RdclZDdE0/ZD89cz1HUlFvWWZJWTs9VXFvZXJNRHNnSUxvUz5FWDxtQ2tfR0ZBWVxcaUV2SURnZ0VBcWVocWdkV2hTYVNPVWRBVUJxZXlNTWNvO2dmXXdPX3Nsc0dFYUlsVXRvZWdnP0VhSVRrU3VgUXJ3b3Z4S3lea2VMXXJdR3ZqW1dKc2hPX2lnQURCd2ddYHZTbUxMSXNSSG9DZExsSE1GUHhmcGtMUHJgXWptUE9GUXh2SWtkTG4+eFZReXNEdHNFTXB0eHZLYU5gYHRobFJsYHFJYFhpaW1TZUo6XFxTaUxVPG1SXUhyYl14QW11ZFRrV2VQUWl1UTxsb3Vydl10TXRXVWFqaXlvOnBuVz1QRT1vTERRXnlMPmBvR2BqWHRMcGx4c2BtamB0W0hPRFBua0RPdGV0dEhxVkhLVT1UZ2xOYWRSXnhVS1lSO1huOzxZR2BQdFFZWFRPbFB0U0RRTkVsaU13XmRzdklwZnRQVWlrSGFsPkxWcXhrWHhSU2hVQ2BUaXB2YUFOO3Bzc1BPRVFwdGxMXm1ySz1NS3lUQ2B1Yz1tRWRwUmB1PUFxZXhqckBSa1VQcVhVR0FMbl1sPkh2Y1hLREB5Y0l2O1FXS3RTVW1VX1VSQmBrUmBNQkRsWFRuYkxucT1ZWFVuVlB0dXR5T2BReGBKZm1VYm1RR3hLbFFtVFFsTFVNaT1SWlhtRmVOYGxYVTx1UWF0eERZWHFRTGFWVVhyZHlVS015QWhrTVFxVERqdXFTVHhwSlRLQnF2XlF5bmxLXWRYbEBzWHBvZ3hSXnFPWGR2R3htWVlXSU1uZlxcT1l1dWVMTT9pUm5lUnd5d2NRUnJQbkZMUEc9VlJQT15pS108UnFwTVlscXVBeFdwWXdxS211ZnlmaXE/XmNAX0RObm5Zd0BvXWs+W15pdUJmaFFJeXJOdUBpbmxwW19XZnVeX1lwXUVBYWxfeV52ZV9gYlBeYWdnYT1BZVJ3YUhBalFvZURPeVZeZV1vcVVHYHk/Y2h3XT1OeHhPXFx3VndabmRrP2JWPnBQVmpQWWpEbmdAeGM9cXBRX2NPSFxcUT5cXF9mYEdmbV5vZG5RYD5YWmRXZVxcR21GRnZzUHVhcHA9YGxGVnRoaVtCeWE9TnFxRnhZWWNtcVxccGZzYUd4O0FcXERRbGRQd0JQcU1mXFxVb25zVnVoSGhYXmZjTm9Rb2NlT2toSXN0aV47cXRaR3RPbnhYP152cWRZUHBqb11oUGw8cWNAVmtUaGVHT3dFb2tuQFtOYWl5Xm1CUWpcXElyY09tT25rPG9rXXF0PXFyPVZvSVZfZF9qWHZ1cWlvd1h3W25jeEhfTFlddGdwdW5kUE5lR3Bpaz52W2l2UkZ0X0d1S25xRkl3XFxuW0RwaHRgdmdJa1phdl9RXU5xdmJBa21IcUFxZ1VPcV9IXlpYakU+Y0BPYklYanRub2ZHbz9xcV5nZWs+dXRAaXVgdHA/bFxcSXBPaHdDYXNcXGFvbmZpSXZtP1BkcVFnTU5oVlFqRmdlREFkU0ZmXFxWZURBZ2hxbFJHXFxVRnFNWWVwcF54dmxQUHZeR15lQGRGP15MQG1LSXVyUV5eeXhLRmlLbm1YR2o6SXZSeW12PmxnT2xyP3E8aHRKSV1sd1tecXVMQF9cXEdmdWdwPD94R3dbbF93P2llZ19pam5cXEReXFxlSW5Cd1s8Z1puSFxcb1FfRkFiVm5hRmFhUmBfPkdgckhuYV5za1BbQEZqaGloPmBiQnBiZ3Z2ckFhQnhwPUFxb3FiQHdfal5xO3FhXFxWdUZxW0B4W1ZAWz9BZ0peW2t4ZXJQZW5ocWZXYWZXeUBxZm1xdmN3WmtuZ1thd3FAb25hXkVHXUtncmJZXV9gXU54XmZHWnJPeGVBYFJGaDpAd0ZOamZoWl1OY2dpcT1ZZGRXXFxiXm1AQGVyRmNncVtMUW1SQXBlQVtxQXhBPnJUR3JCSG1KcHhveGF5cXFpYWdWT2BjSW5bPlteWHJASWhLPmI6WXdtXmtvTnhxZ1tYYGc8UXlDX2dNYFt4X2Z5PnRcXEBmYnhiO0FgaF5oZFFpS1h1ZkZuRkhdTGhxY2hqXmZ5T2VDW2Zjb3dZc3ZScUk7a1dbO3RlR1ZeP1RJVXdXW2V0R0RPbWhsVWZbdWJmY3lpXUlNb2dpd0heVWg6b3dBd2ZXYVJwbXRDQ3U9SUZkQWVeT2hzS3J1ZWVaRVNaVUJeY2luTUlmd0VfbWZza3hKc0VuP2ZPYWNAP0dKPXVYa0RJaUI6cVlPV0JVS1I/PXU/cWdOYXRoP3ZkR0ZQP3VgVXl3XWZDY2NVT3R2VUdZY2k/Q3U9Z1hwXXhJY0l5T3JBbXl4WXhJY1VOS0ZwUURZWVI7Q3dCPXNQcWlGP2VGP0M+VVRZZWY+PVJKTVRcXEVCQ0dVRGloaEtVUl12Z0FlblV2WmlDZWliV2tDY1VCb3Fkb29jd3lDQ19yQGlmO1NzcWtzd19EVm9CdXlZO3lyZHFmdVNjaEFZQVVncVN5U2tnWnVXbWtEPVFjdll3WVtia3NySnNFYUtXaVd1TT11X2djOkVnX1lmTVl0bnFIb2dSaXNFaT14cHNYcV1ncklocldGaUVDeVNVOm1SZV94Z0VCc1tDXFx5Um8/YzpzaWZDZ25bWEhlRFVnV0tvaWljRVBZSXFxSHhrV3dBZ1ljaHFnRGpnSTthRnBLRFdRdl9PQlpZdD5Xd2RBVVl1Ukw7Y295cU51VmhdVXFwdGRpaztwWGR5a3hUUUdsVFF0dlhgWVY9cTpAVm1AcmZUcklUbFR5all0eG9Aam5VU1NIU3NdcV91eXFdc0NlV05NdUhtSz5cXGpXPWx3ZE5aZG9CYFdzcG9QRExvSW1CVUphYVhYbVhQYUxTZW9uPVV1YW1RcW1wRVVXSHNMVHl2RVhUZU9paVl5aXF5PXFxXVhIQVJIYE1fSVFjPFlBZW5IeVFUSW55TWxSWUtLeGtmRVh5QW1ZeVFUPXB0aHlbZHV4QW1DQW1BeVl3VW9zZHlBYFBrUWtVdE95eHJgSVJedG1NTHZlUEw7RFlaZW5yeXZ1PFlHdU5yYHhrUHFQeE1ybW1DPVNAXFx2YXlKa014bnV0Y2F2PkBqVkR2YGxxZG1MO2l3ZlRrQmVMcWxVV1FQZlVYUVh5WnVMZ21zT3lRPUhWQHVOeGVRdXVtckBRT015a0RNY0xtcz1PSEBzUUlVPUhRbV1yeHVqbHV5R3FweFl1TnFVRF1ZeGFyO2F2Q2BtSFxcVTt0UDtsV2t1UXNJSm14TUdNTHZNTmFZUFNgbXJZT2hxWUpAU3JlUXhdVGJIT3JIbGNJbT9FeXBJam5obGtFd2dZbkZ0WG9oSlNVc2xMcnc8a3FgWGNYdUhtUzpJUFBNV15cXG5lTE5yRVlURUxraHlXRFc6cHZAUFJOQVNBcW9xYFlMeFV5dFhaTXZyYFRqbG1rVXE9aFFQUVJ2ZHRTRVhUWVV1VUxxQFl4QVQ/eVNMbVVWZE5vUU5WXFxvS1F3b1VYPW15SkB2XnlyZklzSmRPUj1YPj1XWEBVUkhqeUlWSXVYSUxMU2Bua1xcTHNkTEp4VlhwbWpQcnB5SjpZcWdNU1V1ckZYcWVhV0R4cFdgWTo9UnBQTExhbz9UUU1ETmxgUGRZcDxtWD55WFhFTEVgd1FtVD5dUWV0eVpFVUV4a3I9Uj95cmFJWFRJWWp1dWZpbnJpS1xcQHlTcUtFeFheXXhdYHJYPVI6TFZocFBCbFBlWVlcXGRMYlVOVEBQWGVTXmF3Wml3QXVralhXPDxtZWRqd1BgcXdlWE5ya29oX1lvPWhia1ddd2B3RUBlTldibHdraFhcXGheck5vYk1Rcnl3aUtZa1l5YHlXdF1pZmh5bHReaHlBeFxceFxceUhrVFlrQnhza195akFoPWh2W19eeWZ1YV9kXFw/a3R4YXI+am93Yll5WmxRYVBWbWpeaXdQcT9gW0FIXl5RYHBBeWB3ZFpgY01weXZpXjtGcm14cXl3dFBwd1dOYHFxYVtRZGxYeEpfaHdnWkxfckh4a2lHYVpXcVxceHFNSHdgeHZOQWhJX3Bqd3NMQHBNV3J4Xm9ocWlaP29oeXdeeHg8T3RRV1tjcWxyRmNab2FcXE5dU1diS3dxP2h5a3dqPXldYF9mZU5zZl9aW0BpXnh2eFhgaXZed15mWFdkUXZgdD9icVl2ZlZecXBoa2dubV9oT0lsZm5cXGZ5bm1weFA/eWZ2cHVpZXBuaHlmcnV5aT8+cVlvXnJ4dXhBdTtoeGVpYV93eVlmW0l2XWBIaXE/bkhXeER5XklQWnlobT9RYVZvaldhcFBnbW5JX3hgbl95aW1AYGp5cj9PeXlXXFxgeHFBQHVYTmFIV1xcP3BkQXlrdXZlSUBjO0FxbUl5Q3dcXGVBZj9Pb1dhcFBHeElIcHh5alJmanlha05gZ1VGeGFPY1N2eVlBbD9xZWZudTtmdklgeHRvd0hIcnBXaF5pY1lPaXRxeTxwZHlPbVM+eWluYFxceWE9aG50dm9bZ3RtcHlZVmpreWlPP2J0RmZ1YXhlX2V0eWhsWFp5eVo/eHBBeHlcXD5rWUZ2O1BbdG9gYkl2bEBuX2lmTUlhXVBgSXl5YFBjd154anlxRW5rc19iOm9qZElpPGZ4cFZ5cVF0S1lyeXlhYkhzS3ZcXEU/bFlndmpvdXU+ZHdeZXRIeWpYYHM/eVRxWlVZdVJeXlhgWj95a3hvaXQ/cW4/c0xgXztobGo/XV54ZHNoZ3N5cW1Bb053W3deeXlOW0J2XzxBZ09mdGloYFNJYT1oX2ZwYnhAdUlBZEl2bEhWXmY/YmRZZkBod1NfXzp2aF5Jd19Jb3lQb1ZZYkl2XFw9Vl9KPnA7Rm1oWWVKPnhhbl1iWW94b2l0Q1ZbYkJLZXFxcm9lR0JDST1NSGxReWNJd1tRdjs/Y0FheEo9UnhheV9FZlhLWXJ5eTpveHZjZHI9VFZZQ0N1Q3c/WDpJWDtDSXJJaUFvRWhTRXRpV2txRXQ9dz90S3dcXHg8dmpYbml1XnlBdl1BWWNOaWVkUGdqRDo7al5QTmFMTlFFTmpENUI=</Image></Text-field></Input></Group><Group><Input><Text-field layout="Title" style="Title">Application of Combinatorial Analysis to Flowsheet Synthesis of Chemical Plants</Text-field><Text-field layout="Author" style="Author">Mr. Lee R. Partin, P.E.<Font bold="false" foreground="[0,0,0]" italic="false" underline="false">
Copyright 1994-2000
L R Partin Enterprises
All Rights Reserved</Font><Hyperlink hyperlink="true" linktarget="http://users.chartertn.net/lpartin" style="Text">
http://users.chartertn.net/lpartin</Hyperlink></Text-field></Input></Group><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Introduction</Text-field></Title><Group><Input><Text-field layout="Normal" style="Text">This worksheet demonstrates the use of Maple to generate Microsoft Visio flowsheets of a chemical plant</Text-field><Text-field layout="Normal" style="Text">The following Maple techniques are highlighted:</Text-field><Text-field firstindent="0.0" layout="Bullet Item" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Bullet Item"><Font style="Text">Developing custom functions</Font></Text-field><Text-field firstindent="0.0" layout="Bullet Item" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Bullet Item"><Font style="Text">Creating a a flow</Font></Text-field><Text-field firstindent="0.0" layout="Bullet Item" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Bullet Item"><Font style="Text">Visualizing the flow</Font></Text-field><Text-field firstindent="0.0" layout="Bullet Item" leftmargin="0.0" linebreak="space" rightmargin="0.0" style="Bullet Item"><Font style="Text">Exporting to a Visio diagram</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">The Problem</Text-field></Title><Text-field layout="Normal" style="Normal">The task is to synthesize chemical plant flowsheets to make specified products.  The method requires a toolkit of information about the synthesis problem.  The toolkit includes:</Text-field><Text-field layout="Bullet Item" style="Bullet Item">a set of available raw materials</Text-field><Text-field layout="Bullet Item" style="Bullet Item">a set of required products</Text-field><Text-field layout="Bullet Item" style="Bullet Item">by-product specifications</Text-field><Text-field layout="Bullet Item" style="Bullet Item">a set of unit operation functions that convert inlet materials into outlet materials</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">The first step is to determine the maximal structure which is the set of unit operation functions from the toolkit that assist in making the required products.  Then, the maximal structure is analyzed for all feasible flowsheets.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">Ethanol - water mixtures can be separated using toluene in a distillation process.  The following example shows the synthesis of feasible flowsheets for the process. </Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">A triangular composition diagram was prepared to show several potential unit operations for the process.  The feed is located at point F.  The desired products are pure ethanol (E) and pure water (W).  Toluene (T) is a potential extraction agent for breaking the ethanol-water azeotrope.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">The defined unit operation functions are:</Text-field><Text-field layout="Normal" style="Normal">    1) Mixing:  F+T = A, F+B = J, K+G = L, D+G = O, K+C = M</Text-field><Text-field layout="Normal" style="Normal">    2) Decanting:  A -&gt; B+C,  H -&gt; B+C</Text-field><Text-field layout="Normal" style="Normal">    3) Distillation:  B -&gt; D+W, J -&gt; K+W, L -&gt; E+H, O -&gt; E+H, M -&gt; E+H, C -&gt; G+T</Text-field><Text-field layout="Normal" style="Normal">Note that materials are given names.  A unit operation function is defined by its set of feed materials and its set of product materials.  [{F,T},{A}] defines the first mixer.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">If you wish to read about the technology, here are some good references:</Text-field><Text-field layout="Normal" style="Normal">F. Friedler, K. Tarjan, Y. W. Huang, and L. T. Fan, "Graph-Theoretic Approach to Process Synthesis: Polynomial Algorithm For Maximal Structure Generation," Computer Chem. Engng., Vol. 17, No. 9, 929-942, 1993.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">F. Friedler, K. Tarjan, Y. W. Huang, and L. T. Fan, "Combinatorial Algorithms for Process Synthesis," European Symposium on Computer Aided Process Engineering - 1, ESCAPE-1, May 24-28, 1992, S313-S320.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">F. Friedler, J. B. Varga and L. T. Fan, "Decision-Mapping for Design and Synthesis of Chemical Processes:  Application to Reactor-Network Synthesis," Foundations of Computer Aided Process Design - 1994.</Text-field></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Initialization</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">restart:
interface( warnlevel=0 ):
with( networks ):
with( combinat ):</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Define Functions</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false"># Define the method for Psi- evaluation,
Psi_minus:=proc(OpSet)
           local i, solution;
           solution:={};
           for i from 1 to nops(OpSet) do
             solution:=solution union op(1,op(i,OpSet))
           od;
           solution;
end:

# Define the method for Psi+ evaluation,
Psi_plus:=proc(OpSet)
          local i, solution;
          solution:={};
          for i from 1 to nops(OpSet) do
            solution:=solution union op(2,op(i,OpSet))
          od;
          solution;
end:
# Define the method for phi- evaluation,
phi_minus:=proc(mSet,OpSet)
           local i, solution, item;
           solution:={};
           for i from 1 to nops(OpSet) do
               item:={op(i,OpSet)};
               if (op(2,op(1,item)) intersect mSet) &lt;&gt; {} then
                  solution:=solution union item  fi;
           od;
           solution;
end:

# Define the method for phi+ evaluation,
phi_plus:=proc(mSet,OpSet)
          local i, solution, item;
          solution:={};
          for i from 1 to nops(OpSet) do
            item:={op(i,OpSet)};
            if (op(1,op(1,item)) intersect mSet) &lt;&gt; {} then
               solution:=solution union item  fi;
          od;
          solution;
end:


# Program MSG algorithm,
MSG:=proc(OpSet,RM,Pr)
     local i, item, opset, Mat, o, r, p, m, ox;
     opset:=OpSet minus phi_minus(RM,OpSet);
     Mat:=Psi_minus(opset) union Psi_plus(opset);
     r:=Psi_minus(opset) minus (Psi_plus(opset) union RM);
     if nops(r) &gt; 0 then 
        while r &lt;&gt; {}  do
              item:={op(1,r)};
              Mat:=Mat minus item;
              o:=phi_plus(item,opset);
              opset:=opset minus o;
              r:=(r union (Psi_plus(o) minus Psi_plus(opset))) minus item;
        od;
     fi;
     if (Pr union Mat) &lt;&gt; Mat then
        lprint(`Error:  No maximal structure exists!`); 
        RETURN(`No maximal structure exists!`);
     fi;
     p:=Pr;
     m:={};
     o:={};
     while p &lt;&gt; {}  do
        item:={op(1,p)};
        m:=m union item;
        ox:=phi_minus(item,opset);
        o:=o union ox;
        p:=(p union Psi_minus(ox)) minus (RM union m);
     od;
     m:=Psi_minus(o) union Psi_plus(o);
     [m,o];
end:

# Convert the Pgraph structure into a network,
graph_network:=proc(Structure,naming)
   local i, j, rm, pr, mid, m, mat_order, listing, opset, Gr,
         mat_ins, mat_outs, el, unitnum, inset, outset, inset2, outset2,
         unit_order, unit_order2, unitname, location;
   global  Raw_Materials, Products, OpData, LabelsList;
   m:=op(1,Structure);
   opset:=op(2,Structure);
   # check for material inlets and outlets of the structure
   mat_ins:=Psi_minus(opset);
   mat_outs:=Psi_plus(opset);
   # find all raw materials (they are only inlets to unit ops)
   rm:={};
   # find all products (they are only outlets of unit ops)
   pr:={};
   for el in m  do
       if member(el,mat_ins) and member(el,mat_outs) = false then
          rm:=rm union {el}
       fi;
       if member(el,mat_ins) = false and member(el,mat_outs) then
          pr:=pr union {el}
       fi;
   od;
   mid:=m minus rm minus pr;
   mat_order:=[op(pr)],[op(mid)],[op(rm)];
   # get labels from OpData information
   j:=0;
   for el in opset do
       j:=j+1;
       inset:=op(1,el);
       outset:=op(2,el);
       for i from 1 to nops(OpData) do
           inset2:={op(op(2,op(i,OpData)))};
           outset2:={op(op(3,op(i,OpData)))};
           if inset = inset2 and outset = outset2 then break fi;
       od;
       unitname:=op(1,op(i,OpData));
       member(unitname,LabelsList,'location');
       unitnum[j]:=location;
   od;
   unit_order:={};
   if (naming = 'numbers') then
      unit_order:=[seq(unitnum[j],j=1..nops(opset))];
   else
      unit_order:=[seq(cat(`:`,op(unitnum[j],LabelsList)),
                   j=1..nops(opset))]
   fi;
   unit_order2:=convert(convert(unit_order,set),list);
   listing:=mat_order,unit_order2;
   new(Gr);
   addvertex(op(1,Structure),Gr);
   addvertex(unit_order,Gr);
   for i from 1 to nops(opset) do
       connect(op(1,op(i,opset)),[op(i,unit_order)],directed,Gr);
       connect([op(i,unit_order)],op(2,op(i,opset)),directed,Gr);
   od;
   Linear(listing),Gr;
end:

# Program SSG algorithm,
SSG:=proc(by_prod)
	local mats, e, maps;
	global ox_vals, decision_map, by_prods, Op, Products;
        by_prods:=by_prod;
        mats:=Psi_minus(Op) union Psi_plus(Op);
	ox_vals:=table();
        for e in mats do
            ox_vals[{e}]:=phi_minus({e},Op);
        od;
	SSGmethod(Products,{},{});
        maps:=nops(decision_map);
	`# of decision maps found = `||maps
end:
SSGmethod:=proc(p,m,delta_m)
   local i, j, k, item_x, set_c, testing, item_c, item_y, ox, oy, delta_y, 
         delta_m2, p2, m2, op_y, mat_outs, mat_ins, opmat, pr, el;
   global Raw_Materials, Products, Op, decision_map, ox_vals, by_prods;
   if nops(p) = 0 then
     if by_prods = true then
       # by-products are allowed; accept the solution
       decision_map:=decision_map union {delta_m}
     elif by_prods = false then
       # accept a solution if no by-products are present
       # check for material inlets and outlets of the decision map
       opmat:={seq(op(op(2,op(k,delta_m))),k=1..nops(delta_m))};
       mat_ins:=Psi_minus(opmat);
       mat_outs:=Psi_plus(opmat);
       # subtract the raw materials and products
       mat_ins:=mat_ins minus Raw_Materials minus Products;
       mat_outs:=mat_outs minus Raw_Materials minus Products;
       # for a valid mapping, the intermediate materials must be both
       # inlet and outlet materials
       if ( (mat_ins minus mat_outs) = {} and
	    (mat_outs minus mat_ins) = {} ) then 
          decision_map:=decision_map union {delta_m};
       fi;
     else
       # accept the solution if the by-products are within the input set
       # of allowed by-products.
       # check for material inlets and outlets of the structure
       opmat:={seq(op(op(2,op(k,delta_m))),k=1..nops(delta_m))};
       mat_ins:=Psi_minus(opmat);
       mat_outs:=Psi_plus(opmat);
       # find all products (they are only outlets of unit ops)
       pr:={};
       for el in (mat_ins union mat_outs) do
          if member(el,mat_ins) = false and member(el,mat_outs) then
             pr:=pr union {el}
          fi;
       od;
       # test that the by-products are contained in the by_prods set.
       # accept the solution if true.
       if ((pr minus Products) minus by_prods) = {} then
          decision_map:=decision_map union {delta_m} fi;
     fi;
     if (nops(decision_map) mod 100) = 0 and 
         nops(decision_map) &gt; 0              then
        lprint(nops(decision_map), ` decision maps found so far`)
     fi;
     RETURN(0);
   fi;
   item_x:={op(1,p)};
   ox:=ox_vals[item_x]; 
   set_c:=choose(ox) minus {{}}; 
   for i from 1 to nops(set_c) do
       item_c:=op(i,set_c);
       testing:=0;
       for j from 1 to nops(m) do
           item_y:={op(j,m)};
           oy:=ox_vals[item_y];
           delta_y:={};
           if nops(delta_m) &gt; 0 then 
              op_y:={seq(op(op(2,op(k,delta_m))),k=1..nops(delta_m))};
              delta_y:=phi_minus(item_y,op_y);
           fi;
           if (item_c intersect (oy minus delta_y)) &lt;&gt; {}  or   
              ((ox minus item_c) intersect delta_y) &lt;&gt; {}  then
                testing:=1;
                break;
           fi;
       od;
       if testing = 1  then  next  fi; 
       delta_m2:=delta_m union {[item_x,item_c]};
       p2:=p;
       for j from 1 to nops(item_c) do
           p2:=p2 union op(1,op(j,item_c))
       od;
       p2:=p2 minus (Raw_Materials union m union item_x);
       m2:=m union item_x;
       SSGmethod(p2, m2, delta_m2);
   od;
end:

# Convert a decision mapping into a P graph,
Pgraph:=proc(delta_m)
        local k, m, o;
        o:={seq(op(op(2,op(k,delta_m))),k=1..nops(delta_m))};
        m:=Psi_minus(o) union Psi_plus(o);
        [m,o];
end:

# updating the draw package to show different colors on the graph
`draw/Linear`:=
proc(partitions::specfunc(list,Linear),G::GRAPH,
    origin::list(numeric),xrng::name,yrng::name)
local e,max_x,middle,n,nx,part,shift,t1,text,pos,x,y,
    t,vset,lines,points,i,j,v,center, 
    a,b,c,d,a1,a2,a3,angle,dist; #** add new local vars
options `Copyright 1993 by Waterloo Maple Software`;
    center := [origin[1 .. 2]];
    vset := {};
    n := 0;
    part := table();
    shift := table();
    for t in partitions do
        n := n+1;
        if not type(t,list) then
            ERROR(`partition should be a list`)
        fi;
        shift[n] := 0;
        t1 := select(
            hastype,t,'identical'('offset') = numeric)
            ;
        if t1 &lt;&gt; [] then
            shift[n] := subs({op(t1)},'offset');
            t :=
              select(proc(x) not hastype(x,`=`) end,t)
        else
            if {op(t)} intersect vset &lt;&gt; {} then
                ERROR(
                 `intersecting partitions involving`,t
                 )
            fi
        fi;
        if not type(t,'list'('VERTEX'(G))) then
            ERROR(`not a list of vertices`,t)
        fi;
        part[n] := t;
        vset := vset union {op(t)}
    od;
    userinfo(
        5,'networks',`allocated vertices:`,print(vset)
        );
    if networks['vertices'](G) minus vset &lt;&gt; {} then
        n := n+1;
        t :=
        sort([op(networks['vertices'](G) minus vset)])
        ;
        part[n] := t;
        shift[n] := 0;
        userinfo(
            1,'networks',`adding a new partition`,t)
    fi;
    max_x := origin[1];
    for j to n do
        if max_x &lt; nops(part[j]) then
            max_x := nops(part[j])
        fi
    od;
    middle := 1/2*max_x-1/2+origin[1];
    points := table();
    text := table();
    pos := table();
    x := origin[1];
    for j to n do
        vset := part[j];
        nx := nops(vset);
        x := x+1;
        #** update to shift the alignment of columns
        y := middle-1/2*nx+1/2+shift[j]+origin[2]+0.2*((j mod 3) - 1);
        for i to nops(vset) do
            v := vset[i];
            pos[v] := [x,y];
            points[v] := POINTS(pos[v]);
            if j = n then
                text[v] := 'TEXT'(
                    [pos[v][1]+1.6*10^(-1),pos[v][2]],
                    convert(v,string))
            else
                text[v] := 'TEXT'(
                    [pos[v][1]-.1 ,pos[v][2]],
                    convert(v,string))
            fi;
            y := y+1
        od
    od;
    lines := table();
    for e in edges(G) do
        x := networks['ends'](e,G);
        if 1 &lt; nops(x) then y := x[2]; x := x[1]
        else x := x[1]
        fi;
	if ( type(networks['head'](e,G),integer) or
             substring(convert(networks['head'](e,G),string),1..1) = `:` )
        then
        lines[e] :=
        #** update the line colour and linestyle
        CURVES([pos[x],pos[y]],COLOUR('RGB',1.0,0,0),LINESTYLE(0))
        else
        lines[e] :=
        #** update the line colour and linestyle
        CURVES([pos[x],pos[y]],COLOUR('RGB',0,0,1.0),LINESTYLE(3))
        fi;
    od;
    t := map(
     op,{entries(points),entries(lines),entries(text)}
     );
    xrng := origin[1]+1/2 .. origin[1]+n+1/2;
    yrng := origin[2]-1/2 .. origin[2]+max_x-1/2;
    RETURN(t)
end:

# Calculate statistics for a process network,
netstats:=proc(first,Gr)
          local mat, mats, unitop, unitops, nodes,
                streams, systems, subsystems, loops;
          mat:=[op(op(1,op(1,[first]))),
               op(op(2,op(1,[first]))),
               op(op(3,op(1,[first])))];
          mat;
          mats:=nops(mat);
          unitop:=[op(op(4,op(1,[first])))];
          unitops:=nops(unitop);
          nodes:=mats+unitops;
          streams:=nops(edges(Gr));
          systems:=components(Gr);
          subsystems:=nops(systems);
          loops:=streams-nodes+subsystems;
          `# of materials = `||mats, 
          `# of unit ops = `||unitops,
          `# of network nodes (materials+unit ops) = `||nodes,
          `# of connections = `||streams,
          `# of subsystems = `||subsystems,
          `# of loops = `||loops; 
end:

# Add routines related to generating a graphic flow diagram
# of the process

# Generate Op data structure on available unit operations from
# the full unit operations set data.
OpGen:=proc(OpData)
          local i, Op, count, Labels;
          global LabelsList;
          count:=nops(OpData);
          # setup unique list for the unit operation names
          Labels:={};  
          for i from 1 to count do
              Labels:=Labels union {op(1,op(i,OpData))}
          od;
          LabelsList:=convert(Labels,list);
          # check for the proper number of inlet ports
          for i from 1 to count do
              if nops(op(2,op(i,OpData))) &lt;&gt; 
                 nops(op(6,op(i,OpData)))  then
                 RETURN(`Error: Wrong number of inlet stream port values.  Line=`,i)
              fi;
          od;
          # check for the proper number of outlet ports
          for i from 1 to count do
              if nops(op(3,op(i,OpData))) &lt;&gt; 
                 nops(op(7,op(i,OpData)))  then
                 RETURN(`Error: Wrong number of outlet stream port values.  Line=`,i)
              fi;
          od;
          Op:={};
          for i from 1 to nops(OpData)  do
              Op := Op union {[ {op(op(2,op(i,OpData)))},
                               {op(op(3,op(i,OpData)))} ]};
	  od;
          Op;
end:

# Convert the Pgraph structure into data for a Visio flowsheet plot.
Visio_data:=proc(PGraph,filename)
   local i, j, k, m, opset, rm, pr, mid, el, el2,
         mat_ins, mat_outs, unitnum, place,  
         inset, outset, inset2, outset2, nextunit,
         unitname, matname, port1, port2,  vals,
         max_els, unitprint, routes, route_count, Tree, 
         AP, route_pair, max_route, table_data, route_value,
         route, Gr, Gr2, boxes, location, Streams, nextunitname,
         fileID;
   global  OpData, LabelsList, none, numbers;
   boxes:={};
   m:=op(1,PGraph);
   opset:=op(2,PGraph);
   # generate the network from the PGraph
   Gr:=op(2,[graph_network(PGraph,numbers)]);
   # check for material inlets and outlets of the structure
   mat_ins:=Psi_minus(opset);
   mat_outs:=Psi_plus(opset);
   # find all raw materials (they are only inlets to unit ops)
   rm:={};
   # find all products (they are only outlets of unit ops)
   pr:={};
   for el in m  do
       if member(el,mat_ins) and member(el,mat_outs) = false then
          rm:=rm union {el}
       fi;
       if member(el,mat_ins) = false and member(el,mat_outs) then
          pr:=pr union {el}
       fi;
   od;
   mid:=m minus rm minus pr;
   
   # Print info for all boxes on the diagram,
   fileID:=fopen(`visio.dat`,WRITE,TEXT);
   fprintf(fileID,`%s %s\n`,`File:`, filename);
   # raw materials have the Feed icon
   for el in rm do
       vals[el]:=1;
       fprintf(fileID,`"%s" "towers" "Flowsheet Feed"\n`,el);
       boxes:=boxes union {el};
   od;
   # mid materials use a box icon if they have multiple feeds 
   for el in mid do
       Tree:=shortpathtree(Gr,el);
       if nops(daughter(el,Tree)) &gt; 1 or nops(ancestor(el,Tree)) &gt; 1 then
          vals[el]:=1;
          fprintf(fileID,`"%s" "towers" "Diamond"\n`,el);
          boxes:=boxes union {el};
       else
          vals[el]:=0;
          fprintf(fileID,`"%s" "none" "none"\n`,el);
       fi;
   od;
   # products have the Product icon
   for el in pr do
       vals[el]:=1;
       fprintf(fileID,`"%s" "towers" "Flowsheet Feed"\n`,el);
       boxes:=boxes union {el};
   od;
   # the unit ops have their special icons from OpData
   j:=0;
   for el in opset do
       j:=j+1;
       inset:=op(1,el);
       outset:=op(2,el);
       for i from 1 to nops(OpData) do
           inset2:={op(op(2,op(i,OpData)))};
           outset2:={op(op(3,op(i,OpData)))};
           if inset = inset2 and outset = outset2 then break fi;
       od;
       fprintf(fileID,`"%s" "%s" "%s"\n`,op(1,op(i,OpData)),op(4,op(i,OpData)),
                 op(5,op(i,OpData)) ) ;
       member(op(1,op(i,OpData)),LabelsList,'location');
       unitnum[j]:=i;
       boxes:=boxes union {location};
   od;
   # print the stream connectivity data
   # source node, destination node, source port, dest. port, label
   fprintf(fileID,`Stream Data:\n`);
   # cycle through all units in the process
   Streams:={};
   for i from 1 to nops(opset) do
       unitname:=op(1,op(unitnum[i],OpData));
       # do inlets to the unit
       for el in op(1,op(i,opset)) do
           matname:=el;
           member(matname,op(2,op(unitnum[i],OpData)),'place');
           port2:=op(place,op(6,op(unitnum[i],OpData)));
           if {el} intersect rm &lt;&gt; {} then 
              Streams:=Streams union
                 {[matname,unitname,1,port2,none]}
	   elif vals[el] = 1 then
              Streams:=Streams union
                 {[matname,unitname,5,port2,none]}
           else
              nextunit:=arrivals(el,Gr);
              nextunitname:=op(op(nextunit),LabelsList);
              for k from 1 to nops(OpData)  do
                  if op(1,op(k,OpData)) = nextunitname then
                     if member(matname,op(3,op(k,OpData)),'place')
                        then break  fi;
                  fi;
              od; 
              port1:=op(place,op(7,op(k,OpData)));
              Streams:=Streams union
                 {[nextunitname,unitname,port1,port2,matname]}
           fi;
       od;
       # do outlets of the unit
       for el in op(2,op(i,opset)) do
           matname:=el;
           member(matname,op(3,op(unitnum[i],OpData)),'place');
           port1:=op(place,op(7,op(unitnum[i],OpData)));
           if {el} intersect pr &lt;&gt; {} then 
              Streams:=Streams union
                 {[unitname,matname,port1,2,none]}
           elif vals[el] = 1 then
              Streams:=Streams union
                 {[unitname,matname,port1,3,none]}
           else
              NULL;  # the connection was already made
           fi;
       od;
   od;
   # print the stored stream connectivities,
   for el in Streams do
       fprintf(fileID,`"%s" "%s" "%d" "%d" "%s"\n`,op(el))
   od;
# print the main route through the process followed by sets
# with the other units.
   fprintf(fileID,`Routes:\n`);
   # find all routes from feeds to products,  tag the longest one
   max_els:=0;
   for el in rm do
       Tree:=shortpathtree(Gr,el);
       for el2 in pr  do
           # Note: path returns the vertices in reverse order
           routes[el,el2]:=path([el2,el],Tree);
           # count only the vertices that are part of the diagram
           route_count[el,el2]:=
              nops({op(routes[el,el2])} intersect boxes);
           # find the maximum pathway
           if route_count[el,el2] &gt; max_els then
              route:=el,el2;
              max_els:=route_count[el,el2];
           fi;
       od;
   od;
   # print the maximum route  (it is in reverse order)
   fprintf(fileID,`%d\n`,max_els);
   k:=nops(routes[route]);
   for i from 1 to k  do
       j:=k+1-i;
       if {op(j,routes[route])} intersect boxes &lt;&gt; {} then
          unitprint:=op(j,routes[route]);
          if whattype(unitprint) = integer then  
             fprintf(fileID,`"%s"\n`,op(unitprint,LabelsList))
          else
             fprintf(fileID,`"%s"\n`,unitprint);
          fi;
       fi;
   od;
   # if there are more than 1 box left, then find the longest path
   # through them and output it.
   boxes:=boxes minus {op(routes[route])};
   if nops(boxes) &gt; 1  then
       # get a new graph with only the remaining vertices
       new(Gr2);
       for el in boxes do
           Gr2:=gunion(Gr2,induce(incident(el,Gr),Gr),'SIMPLE');
       od;
       # find the distances for all pairs
       AP:=allpairs(Gr2);
       # find the maximum distance
       route_pair:=0,0;
       max_route:=0;
       table_data:=op(op(AP));
       for i from 1 to nops(table_data) do
           route_value:=op(2,op(i,table_data));
           if route_value &gt; max_route and route_value &lt; infinity then
              max_route:=route_value;
              route_pair:=op(1,op(i,table_data));
           fi;
       od;
       # find the route between the route_pair set
       Tree:=shortpathtree(Gr2,op(1,[route_pair]));
       route:=path([op(2,[route_pair]),op(1,[route_pair])],Tree);
       # print the number of units in the path and their names in reverse
       fprintf(fileID,`%d\n`,nops({op(route)} intersect boxes));
       k:=nops(route);
       if k &gt; 1 then
          for i from 1 to k  do
              el:=op(k+1-i,route);
              if ({el} intersect boxes)  &lt;&gt; {} then 
                 if whattype(el) = integer then 
                   fprintf(fileID,`"%s"\n`,op(el,LabelsList))
                 else
                   fprintf(fileID,`"%s"\n`,el)
                 fi;
              fi;
          od;
       else 
          fprintf(fileID,`0\n`);
          route:=[];
       fi;
   else
       fprintf(fileID,`0\n`)
   fi;
   # if there are more than 1 box left, then find the longest path
   # through them and output it.
   boxes:=boxes minus {op(route)};
   if nops(boxes) &gt; 1  then
       # get a new graph with only the remaining vertices
       new(Gr2);
       for el in boxes do
           Gr2:=gunion(Gr2,induce(incident(el,Gr),Gr),'SIMPLE');
       od;
       # find the distances for all pairs
       AP:=allpairs(Gr2);
       # find the maximum distance
       route_pair:=0,0;
       max_route:=0;
       table_data:=op(op(AP));
       for i from 1 to nops(table_data) do
           route_value:=op(2,op(i,table_data));
           if route_value &gt; max_route and route_value &lt; infinity then
              max_route:=route_value;
              route_pair:=op(1,op(i,table_data));
           fi;
       od;
       # find the route between the route_pair set
       Tree:=shortpathtree(Gr2,op(1,[route_pair]));
       route:=path([op(2,[route_pair]),op(1,[route_pair])],Tree);
       # print the number of units in the path and their names in reverse
       fprintf(fileID,`%d\n`,nops({op(route)} intersect boxes));
       k:=nops(route);
       if k &gt; 1 then
          for i from 1 to k  do
              el:=op(k+1-i,route);
              if ({el} intersect boxes)  &lt;&gt; {} then 
                 if whattype(el) = integer then 
                   fprintf(fileID,`"%s"\n`,op(el,LabelsList))
                 else
                   fprintf(fileID,`"%s"\n`,el)
                 fi;
              fi;
          od;
       else 
          fprintf(fileID,`0\n`);
          route:=[];
       fi;
   else
       fprintf(fileID,`0\n`)
   fi;
   # print the remaining units in the order of 1) raw materials
   # 2) mid materials, 3) unit ops, and 4) products
   boxes:=boxes minus {op(route)};
   fprintf(fileID,`%d\n`,nops(boxes));
   for el in boxes  do
       if ({el} intersect rm) &lt;&gt; {}  then fprintf(fileID,`"%s"\n`,el) fi
   od;
   for el in boxes  do
       if ({el} intersect mid) &lt;&gt; {} then fprintf(fileID,`"%s"\n`,el) fi
   od;
   for el in boxes  do
       if whattype(el) = integer then 
       fprintf(fileID,`"%s"\n`,op(el,LabelsList))   fi
   od;
   for el in boxes  do
       if ({el} intersect pr) &lt;&gt; {}  then fprintf(fileID,`"%s"\n`,el) fi
   od;
   fprintf(fileID,`End:\n`);
   close(fileID);
end:

# calculate the rank value of a decision mapping
rank_value:=proc(mapping)
   local el, i, m, opset, rankings, inset, outset, inset2, outset2,
         unitname, unitrank, PGr, tabledata, sumrank, mat_ins,
         mat_outs, rm, pr;
   global OpData, Material_Rank;
   # rankings is a table for storing the rank of each unit op
   rankings:=table();
   # the inputted decision map is converted to a P graph (m,o)
   PGr:=Pgraph(mapping);
   m:=op(1,PGr);
   opset:=op(2,PGr);
   # check for material inlets and outlets of the structure
   mat_ins:=Psi_minus(opset);
   mat_outs:=Psi_plus(opset);
   # find all raw materials (they are only inlets to unit ops)
   rm:={};
   # find all products (they are only outlets of unit ops)
   pr:={};
   for el in m  do
       if member(el,mat_ins) and member(el,mat_outs) = false then
          rm:=rm union {el}
       fi;
       if member(el,mat_ins) = false and member(el,mat_outs) then
          pr:=pr union {el}
       fi;
   od;
   # cycle through the unit ops within opset to find their location
   # within the OpData array;  extract the name &amp; rank for rankings table
   for el in opset do
       # match the unit op to its row within OpData
       inset:=op(1,el);
       outset:=op(2,el);
       for i from 1 to nops(OpData) do
           inset2:={op(op(2,op(i,OpData)))};
           outset2:={op(op(3,op(i,OpData)))};
           if inset = inset2 and outset = outset2 then break fi;
       od;
       # extract the name and rank
       unitname:=op(1,op(i,OpData));
       unitrank:=op(8,op(i,OpData));
       # store the info within the rankings table;  use the highest
       # ranking that occurs for a given unit name
       if whattype(rankings[unitname]) = indexed  then
           rankings[unitname]:=unitrank
       else
           if rankings[unitname] &lt; unitrank then 
              rankings[unitname]:=unitrank fi;
       fi;
   od;
   # Get the data from inside the rankings table
   tabledata:=op(2,op(1,rankings));
   # Sum the ranks of the unit operations
   sumrank:=convert([seq(rhs(op(i,tabledata)),i=1..nops(tabledata))],`+`);
   # Add the ranks of the raw materials and products within the flowsheet
   m:=rm union pr;
   for el in m  do
       if whattype(Material_Rank[el]) &lt;&gt; indexed then
          sumrank:=sumrank+Material_Rank[el]  fi; 
   od;
   sumrank;
end:

# provide the sort criteria for the flowsheets list; sort by
# increasing rank value.
sort_rank:=proc (a, b)
   #  note:  the rank is stored as the first element of the list
   if op(1,a) &lt; op(1,b) then  true
   else  false
   fi;
end:

# add the rank to each decision mapping and sort it
process_maps:=proc(dm) 
   local j;
   global  flowsheets;
   # create a list containing lists with the flowsheet rank and its
   # decision map.
   flowsheets:=[seq([rank_value(op(j,dm)),op(j,dm)],
                j=1..nops(dm))];
   # sort the list by increasing rank; the sort_rank function provides
   # the boolean function for the sorting task.
   flowsheets:=sort(flowsheets,sort_rank);
   flowsheets;
end:

# use cycles in the flowsheet to determine key material
# balance requirements,
cycles:=proc(first,Gr,rootVertex)
   local el, el2, edgeset, Grund, G2, eset, G3, cyc, G4,
         cycleVertices, chords, numberChords, units,
         cycleFeeds, cycleProducts;
   global LabelsList, Raw_Materials;
   # first, generate an undirected graph from Gr
   edgeset:={};
   for el in edges(Gr) do
       edgeset:=edgeset union {{head(el,Gr),tail(el,Gr)}};
   od;
   Grund:=graph(vertices(Gr),edgeset);
   # find a spanning tree of Grund rooted at a raw material,
   G2:=spantree(Grund,rootVertex);
   # find the chords of the spanning tree,
   chords:=edges(Grund) minus edges(G2);
   # if there are no chords then stop,
   numberChords:=nops(chords);
   if numberChords = 0 then  RETURN(`No loops found.`)  fi;
   # loop through all fundamental cycles,
   for el in chords  do
      # add a chord to the edge set
      eset:={el} union edges(G2);
      # find the fundamental cycle
      cyc:=fundcyc(eset,Grund);
      # create a subgraph from the cycle
      G3:=induce(cyc,Grund);
      # find the vertices in the graph
      cycleVertices:=vertices(G3);
      # delete any vertices that are raw materials or products
      for el2 in cycleVertices do
          if nops(arrivals(el2,Gr)) = 0 then
             cycleVertices:=cycleVertices minus {el2} fi;
          if nops(departures(el2,Gr)) = 0 then
             cycleVertices:=cycleVertices minus {el2} fi; 
      od;
      # create a new graph from the original Gr with
      # the condensation of the cycleVertices,
      G4:=duplicate(Gr);
      shrink(cycleVertices,G4,new_vertex);
      # print results,
      units:={};
      for el2 in cycleVertices do
          if whattype(el2) = integer then
             units:=units union {op(el2,LabelsList)}
          else
             units:=units union {el2}
          fi;
      od;
      cycleFeeds:={};
      for el2 in arrivals(new_vertex,G4) do
          if whattype(el2) = integer  then
             cycleFeeds:=cycleFeeds union {op(el2,LabelsList)}
          else
             cycleFeeds:=cycleFeeds union {el2}
          fi;
      od;
      cycleProducts:={};
      for el2 in departures(new_vertex,G4) do
          if whattype(el2) = integer  then
             cycleProducts:=cycleProducts union {op(el2,LabelsList)}
          else
             cycleProducts:=cycleProducts union {el2}
          fi;
      od;
      lprint(`Cycle found:`);
      lprint(`Fundamental cycle vertices (w/o RM's and Pr's) = `, units);
      lprint(`Feeds from =`,cycleFeeds);
      lprint(`Products to =`,cycleProducts);
   od;
   `# of cycles processed = `||numberChords;
end:</Font>
</Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Define Materials</Text-field></Title><Text-field layout="Normal" style="Normal">All materials are given unique identifying names and listed by their functions.</Text-field><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Raw Materials</Text-field></Title><Text-field layout="Normal" style="Normal">Input the set of raw materials</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Raw_Materials:={F}:</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Products</Text-field></Title><Text-field layout="Normal" style="Normal">Input the set of required products</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Products:={W,E}:</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Unit Functions</Text-field></Title><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Documentation of Unit Functions</Text-field></Title><Text-field layout="Normal" style="Normal">The unit operation functions are entered as lists within OpData.  OpData handles</Text-field><Text-field layout="Normal" style="Normal">several tasks:</Text-field><Text-field layout="Bullet Item" style="Bullet Item">It gives a name for each unit operation function to be used as identifiers in flowsheet plots.</Text-field><Text-field layout="Bullet Item" style="Bullet Item">It defines the inlet and outlet materials of each unit operation function.</Text-field><Text-field layout="Bullet Item" style="Bullet Item">It provides data for plotting the flowsheet as a Visio drawing.</Text-field><Text-field layout="Bullet Item" style="Bullet Item">Each unit operation function is linked to a shape within a Visio stencil.</Text-field><Text-field layout="Bullet Item" style="Bullet Item">The inlet and outlet materials are attached to connection ports on the Visio shapes as defined in the connection section of the Visio shape.</Text-field><Text-field layout="Bullet Item" style="Bullet Item">Each unit operation function is given a rank.  The rank should be a positive number (or zero) that sets its relative cost when compared to the other unit functions in the list.  The individual ranks are summed and added with ranks based on materials to give an overall ranking for each generated flowsheet.  The flowsheet ranks are then used to sort the list by increasing rank.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">Note:  The same unit label can be given for multiple unit operation functions.  In the example OpData, `Decant1` is used twice to produce the products of B and C from either A or H as feeds.  The flowsheet plot then shows `Decant1` with A, H or A &amp; H as the feed(s) to the shape.  For the case with A &amp; H as feeds, the overall rank is calculated using the higher rank of the two functions. </Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">Definitions:</Text-field><Text-field layout="Normal" style="Normal">unit label = a name given to the unit operation function for plotting purposes</Text-field><Text-field layout="Normal" style="Normal">feeds = a list of its inlet materials</Text-field><Text-field layout="Normal" style="Normal">products = a list of its outlet materials</Text-field><Text-field layout="Normal" style="Normal">stencil = the Visio stencil to be used for its shape on the flowsheet drawing.  The VB program for plotting Visio flowsheets recognizes the several stencils.  Enter</Text-field><Text-field layout="Normal" style="Normal">pumps for 'Process Flow - Pumps and Compressors' stencil;  enter heateq for</Text-field><Text-field layout="Normal" style="Normal">'Process Flow - Heat Equipment' stencil; enter vessels for 'Process Flow - Vessels'</Text-field><Text-field layout="Normal" style="Normal">stencil; enter equip for 'Process Flow - Equipment' stencil;  enter towers for </Text-field><Text-field layout="Normal" style="Normal">'Towers' stencil.</Text-field><Text-field layout="Normal" style="Normal">icon name = the icon name within the Visio Stencil</Text-field><Text-field layout="Normal" style="Normal">feed ports = a list of integers giving the corresponding connector ports for each feed</Text-field><Text-field layout="Normal" style="Normal">product ports = a list of integers giving the corresponding connector ports for each product</Text-field><Text-field layout="Normal" style="Normal">rank = a rank factor for the given unit operation function</Text-field></Section><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Unit Function Entry</Text-field></Title><Text-field layout="Normal" style="Normal">         [unit label, feeds, products, stencil, icon name, feed ports, product ports, rank ] </Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">OpData:=
[ [`Mix1`,[F,T],[A],`towers`,`Mixer`,[3,1],[5], 0 ] ,
[`Decant1`,[A],[B,C],`towers`,`Decanter`,[1],[2,3],1],
[`Distill1`,[B],[D,W],`towers`,`Full Column 2 Sections`,[1],[7,8], 10],
[`Distill2`,[C],[G,T],`towers`,`Full Column 2 Sections`,[1],[7,8], 10],
[`Mix2`,[G,D],[O],`towers`,`Mixer`,[3,1], [5], 0 ],
[`Distill3`,[O],[H,E],`towers`,`Full Column 2 Sections`,[1],[7,8], 10],
[`Decant1`,[H],[B,C],`towers`,`Decanter`,[1],[2,3], 1 ],
[`Mix3`,[F,B],[J],`towers`,`Mixer`,[3,1], [5], 0 ],
[`Distill4`,[J],[K,W],`towers`,`Full Column 2 Sections`,[1],[7,8], 10],
[`Mix4`,[G,K],[L],`towers`,`Mixer`,[3,1], [5], 0 ],
[`Distill3`,[L],[H,E],`towers`,`Full Column 2 Sections`,[1],[7,8], 10],
[`Mix5`,[C,K],[M],`towers`,`Mixer`,[3,1], [5], 0 ],
[`Distill3`,[M],[H,E],`towers`,`Full Column 2 Sections`,[1],[7,8], 10]     ]:</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Op:=OpGen(OpData):</Font></Text-field></Input></Group><Text-field layout="Normal" style="Normal"/></Section></Section></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Define Rank Factors for Materials</Text-field></Title><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Documentation of Material Rank Factor</Text-field></Title><Text-field layout="Normal" style="Normal">The flowsheet ranking can also include rank factors for the materials that are present in the flowsheet.  The rank factors only apply to materials that are either raw materials or products in the given flowsheet.  The raw materials must be within the Raw_Materials set as defined previously.  The products are either from the Products set as defined previously or they are by-products.  Note that the internal material streams can become by-products in some generated flowsheets.  An input flag to the SSG procedure controls the presence of by-products.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">The material rank can be positive for a cost such as a raw material or a by-product that requires disposal.  It can be negative for a product.</Text-field></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Material Rank Definition</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Material_Rank:=table():  # required to define the table</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Material_Rank[F]:=0:  # example entry for material F</Font></Text-field></Input></Group></Section></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Generate of Maximal Structure</Text-field></Title><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Definition of Maximal Structure</Text-field></Title><Text-field layout="Normal" style="Normal">The maximal structure (if it exists) is the collection of unit operation functions from the toolkit that are valid for making the required products from the available raw materials.  It is a feasible flowsheet solution to the synthesis task.  The maximal structure may contain several smaller flowsheets that are also solutions to the synthesis task.</Text-field></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Calculation</Text-field></Title><Text-field layout="Normal" style="Normal">The MSG procedure generates a P graph for the maximal structure that contains all of the useful unit operation functions for the synthesis task.  The procedure requires three  sets defining the unit operation functions, the raw materials and the required products.  The sets were calculated in the previous sections of the worksheet.</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">maximal_structure:=MSG(Op,Raw_Materials,Products);</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Simple Network Plot of Maximal Structure</Text-field></Title><Text-field layout="Normal" style="Normal">The network draw capabilities of Maple provide a simple method of plotting the flowsheet diagrams.  The draw procedure was modified to allow show the feed streams to a unit as solid red lines and the products from a unit as dashed blue lines.  The network for the maximal structure is drawn next.</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">draw(graph_network(maximal_structure,names));</Font></Text-field></Input></Group></Section></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Generate All Feasible Processes</Text-field></Title><Text-field layout="Normal" style="Normal">The SSG procedure finds all of the individual flowsheets from within the maximal structure that meet the criteria.  Op is the set of unit operation functions that were accepted into the maximal structure.  decision_map is initialized to the null set. The SSG procedure adds decision maps to decision_map as it finds them.  Decision maps store flowsheet connectivity data.</Text-field><Text-field layout="Normal" style="Normal"/><Text-field layout="Normal" style="Normal">SSG has one input value.  Its values are defined as:</Text-field><Text-field layout="Normal" style="Normal">true = allow internal materials to become byproducts</Text-field><Text-field layout="Normal" style="Normal">false = do not allow internal materials to become byproducts</Text-field><Text-field layout="Normal" style="Normal">set of materials = allow the materials in the set to be byproducts, (i.e., { H } )</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Op:=op(2,maximal_structure):</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">decision_map:={}:</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">SSG(false);  # false for no by-product</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Calculate Rankings of Synthesized Flowsheets</Text-field></Title><Text-field layout="Normal" style="Normal">The following Maple code calculates the ranking of each flowsheet, sorts the results in ascending order and prints a listing of the ranks.</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">FlowsheetRankings:=process_maps(decision_map):
lprint(`Flowsheet Rankings`);
lprint(`#   Rank`);
for i from 1 to nops(FlowsheetRankings) do
   lprint(i,FlowsheetRankings[i][1])
od;</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 1" style="Heading 1">Analyze a Specific Flowsheet</Text-field></Title><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Set Desired Flowsheet Order Number</Text-field></Title><Text-field layout="Normal" style="Normal">The flowsheets were ordered by the cost ranking in the previous section.  You select a given flowsheet from the ranking by its order number (1, 2, etc) in the ranking of the results.</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">selection:= 1;</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">PGr:=Pgraph(FlowsheetRankings[selection][2]):</Font></Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">rank_value:=FlowsheetRankings[selection][1];</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Draw the flowsheet as a simple network drawing</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">draw(graph_network(PGr,names));</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Draw the flowsheet as a Visio process flow drawing</Text-field></Title><Text-field layout="Normal" style="Normal">The `Visio_data` procedure extracts the required information from the flowsheet for drawing it as a process flow diagram.  The data are printed to an ASCII file called `VISIO.DAT`.  A VBA macro within Visio can then read the data file and plot the process flowsheet within a Visio drawing.</Text-field><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Prepare the Visio data file</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Visio_data(PGr,`fsheet`||selection);</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Plot the flowsheet within Visio</Text-field></Title><Text-field layout="Normal" style="Normal">Next, start the Visio program and create a new drawing based on the Chemical_Flowsheet template within the Industrial Process directory.  You need Visio Technical 4.5 or higher to execute the template.  Instructions are provided within the template.  Two Visio files are used for the software:</Text-field><Text-field layout="Normal" style="Normal">Chemical Flowsheet.vst   &amp;  Towers.vss</Text-field><Text-field layout="Normal" style="Normal">Place the two files within the Visio\Solutions\Industrial Process subdirectory.</Text-field></Section></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Calculate network statistics</Text-field></Title><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">netstats(graph_network(PGr,numbers));</Font></Text-field></Input></Group></Section><Section collapsed="true"><Title><Text-field layout="Heading 2" style="Heading 2">Determine material balance constraints</Text-field></Title><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Documentation</Text-field></Title><Text-field layout="Normal" style="Normal">The cycles procedure analyzes the flowsheet for special material balance constraints.  It uses graph theory to analyze an undirected graph of the flowsheet for fundamental cycles.  The results give information on important material balance constraints.  A process will not be feasible if the constraints can not be met.  The feeds must equal the products for each cycle.  The first input to cycles gives the P-graph of the given flowsheet.  The second input is a raw material or product that is used as the root of a spanning tree of the undirected graph.</Text-field></Section><Section collapsed="true"><Title><Text-field layout="Heading 3" style="Heading 3">Calculate material balance constraints</Text-field></Title><Text-field layout="Normal" style="Normal">Define <Equation input-equation="Material" style="2D Math">NiMlKU1hdGVyaWFsRw==</Equation> as a material from either the <Equation input-equation="Raw_Material" style="2D Math">NiMlLVJhd19NYXRlcmlhbEc=</Equation> or <Equation input-equation="Products" style="2D Math">NiMlKVByb2R1Y3RzRw==</Equation> sets.  The material is used as the root in spanning tree analysis.  You can repeat the cycle determinations with different root materials.</Text-field><Group><Input><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">Material:=Products[1];</Font></Text-field></Input></Group><Group><Input><Text-field layout="Normal" style="Normal">Next, calculate `cycles` to determine the material balance constraints that are related to the cycles that it finds.  The Feeds must equal Products for each of the cycles to maintain the material balance.</Text-field><Text-field layout="Normal" prompt="&gt; " style="Maple Input"><Font italic="false" underline="false">cycles(graph_network(PGr,numbers),Material);</Font></Text-field></Input></Group></Section></Section></Section><Group><Input><Text-field layout="Normal" style="Text"/><Text-field layout="Normal" style="Text"><Font italic="true">Legal Notice: The copyright for this application is owned by the author(s). Neither Maplesoft nor the author are responsible for any errors contained within and are not liable for any damages resulting from the use of this material.. This application is intended for non-commercial, non-profit use only. Contact the author for permission if you wish to use this application in for-profit activities.</Font>
</Text-field></Input></Group><Group><Input><Text-field alignment="centred"><Image height="33" width="800">TUZOV3RLVWI8b2I8Uj1NRExDZE5WWlpKOkBMPkg6VEtHeE1rSjo8T2BMb1xcbFF4bFFXZE1XcHNIcVNobVdoWW9lWE9QbVRQbVZgbXZxeXhxPVhqPXhYcXVYYXhuYVhjRVdjPVVSPVV3ZVl3RUxLRExxdFBxPFI6PXJeYXZedVJBdXJaQG5adFZhdVZiPVdiTVl0TXl2YXl2WXl1WVl4bVl4cXl4cVl5dVl5RVlzRVlwbVhweXl5eXlwcXhwPUo6Pjo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6Ojo6OjpkeTxUeXBDPnFVTENUSmNEWG9YdXNUPGF1cGtjZldNWEBKQ2VVYGROdVRtV3h5eXlwcHVQQ0RTU3VMQ2x1Pjx4VHBRbWxzYl1NaWhVT2BxVGVYU1FPO0BKeFZdd09sOkBzeUZ2PHdcXHRAdHNOblFuXFxWP3c8d1xcP0ZxSmlqWHluWlZ2bnlIRXJtaUJfX3RXaXRbTXl4WVJJSVh2V2d0U1M9O2dRTXdBSUNdSVlyR1hSb2djW0VwcVl0c3huPUJWU1VHdUVBW1d4S3JXYVNIc3NvWUJQa3luS2N0cWdteVVLQVlRWVV3X3JzPXdib1lUV1hJP0lRS3lvW1hAd3lkcXl0WVJHQXlgaXhzW1NseVhhU3lxdXk6bWVsPWRYcXlkSWZ2Z1JJZVNVa1VtVUJHd3VaaXRTO2VRP1M+QWRNYXNua3lTR2JEU3VpbWJTYWJqeXROQXlNdVhsYVRXYUNwO3k/YXQ7X3R4YVR3YXRoP2NqPUdiZ1lWR0NBW2VBa2heaWh5YUlHb1ZkR3h5V2VRYXRhbVZIWXg6U0VJZXd5YWNtY1NCQXZnT3l5c3NFeUJWV0N3UUZ0WVd4WWRNZ2NZX3leVXk/Z2NlW1dYUUNEY3dHdXdITXc/cXd4W2dhY3NjR3J3T3R1S0ZYS3NjW0ZaSUJPcUlySUlda3VJQ2ZSb3NNX3lUU0VXV2NLUXNfcUdIZUlpYVdCc3ZhQVhXb0ZzWVR5dUlZU2RXQ2V0W2ZacE9ZdHZbXFxYU012Tj1YaGx1eGVsXXlsdlVuO1BZc3F2a21tQ3hTRVFQc01PZVVwUUVLTmB5VkFxY3FSUXBZeEhyW3hVXFxBdGdQVmV4bUhIUVlEWHB0TDtleV9cXFhIeHlUcExRPXFKaEprbHFBPXdQeHFPdHBQbXdRPWtXZFNTWWp4aFF0PWxpPFg9UHJcXEhveE1LeHBwZFVQR3hsYDxSYWRXc0VNVWhuTWluYXF2eVxcdF1wSndcXFB0dHQ6bHdfaHk7UHh1RWxXcGZ5cGlReWc8SWJnSHFRP3dSd3ZGZ2NRbm10SV1sWFpvYXV2d1xcXVZpXFw/eXVJakdxeUFfXWpeY2lhXFxedmFZZm1YWXZWX2ZveWRfd1phP3lJUGZOWHBPaW1iSW53aWllUXlaQFtqZltwX2BzP1xcTkBxYXdbPGFfPXFwZEl1XT5nbkhwVWlcXF5hW0FHY1NfeV1wbkhnX29JaT1Ya01gYkteeVVXakZoaENwaWY/bGxoZWxoa0txaz1xZ0NxcUlva0phZFpAXUlPc3BIamdRZ1V2Xk1wXltha1hOb2t4Y0ZheE1YPkVmeD1HSnlZXT11S1dYdWVmY1lDVl9ETztYXW9lRHdJXVVyaElYaEtkdFlndj1zWU14eU1oRUFiZEtkRkVEO01CaW1VWWd2TnNmQnVEZ3F3XnNSWm9pZXlpWUVmRUFzWU9jVTt1Zl9DXjtnPkVJVW1XeV14WltIP1VUaXdoYXliPEVXVUFobWdoVWVlXU9ETHlma1lkT1FETk1zbGVnXW1IR2t5blVyclVoamdidnN0cklDc09pVT91cFVodE1FX2NWVWV5d1dyU2VTdkl3SHFzRVV2d2FTYG12X2tDRWdERUVWT295ZlNGWUdYaFt4ZTt3ZnN5YT9IYmN1X1NpSFVmclN0cXNnSUNVS21SO0lFR0dpRVV4U1Nld2tCUmNpYz9mW0dIc11XQkNlRlNYTWVjQHF3UVlpT0NGaTtiZF9lcGdoQ2NyU0liclVGZktYcE9FPkNkR1VWSF9zcz1HYUVGXFxNaF91REpjWGVXR1NrSUE9VGBbdWhPaUtPeTtJZG9fc0JRZ1BHYmlNeFpJeFs9Uk5RSENVd2xJaFZBcz5NeHY9dDtJZWtlY1tpVG9lQl1ZU1ZzSV1VR2tNZ0M9eE1fY3ZdckNrR2xPeUU9d1ZzeW1vUlBFUkdVV29Lcz4/ZE5HY3FPdkw9RGNnVVVpZD1TZEJZdGFjQmN5VDtzQz8/c1hzQkZFSVBLZHdVaWJVVXVvd3RDeExFUnhHVVBPYz1lZVdXREpfdEJJRmpbUk1XWG9hSW5pRkRZeXZJZkZZSDtFaWZhV0FBZGtRZ1N1SW9ZSFM/c1xcYVlua1ljQ1JYQXk7PXVyU3NVRUdYb3Zta2RVP2JJa3V2SWhmO2hIS1Jtc0lxa0drQ0lFR1NRaVV5P3JbY2h5XURXP1VKd2VvX0hJO0lbaVJQdVlDY2VdeUlRR1NSPVNGY1lASUhOYWJFeWhUO0hcXGdDW2lpRXViWElZWz9GaGtmQWFSeWNjUTtEPE1CTGtzVUd2TV1GT1NXWmFGbm1VVk9CXU1oYGd1XWV3OkNTWFtWVVtkXmlXQ0lUTWtpbmdWbWNZO0V1SWtGWmdldGFTbGtlRF9TbFVkP1NVW1doYF9JSGt1TmFJQkVZQEtoUVtJYlNmbF9DcGdWXUlCZ2NmOkNyT1dXbGlWUFNETXVFa3dCWVFiZ0t4R2lXZmNkZ19jQ29YRHlGb0FGPENZZF9mWlNVS09YbVVFcm12cFdnYVFJZVdHeU1pdU9maGVGWVtVV2dkR3dlWztYQFloPG93c2tUd1VnallkdkVoblRQYExKYXRVbXlvXXhsa1VwZ1BTSG1TT2lTWHRNP0hzSGhXZ2xudT15cE1vc21QV1F0WG1sTERSXmVyYXBwQVBxQFR3dVxcbWY8eXRNb190TlFEbXd1VUJhbFtUS01dVVpcXFZzVVBnXFxPaFhVXWl3PmxUPlR0b2xZVWVNXFxgcTppTkZRa01ldUI8WV55cVtUcXdMeHlZa15tUERoVVRFTFtteGRZVHJVd0hZcHBgUl10c3lobTxcXHJkaE5cXF1WR2VqRXlUQkxsWGhVaWRTa2xWY0lta3VKQVxcT0ZBSnhYVEpcXG9ScFVyXFxxbkVVZjxQT2FvY2lvWHhZVVRSeGhtS0hub1V1QmF2dnh0XUBvcmR5cUlsYHR5Y0V5Zz1TdDxWO0xZYERvREVsQ2hXWWRrcElrU01vcGhuaHFrZU1XPFFYXmRvZ0VtTTxreEFZTT1tcFBLbVRUTW1YZVFMbnVLP0hNZUlVYGBUcU1TZGVOcW14SGVMSz1PVXB4XkBraVlwYHhYVmRvVUBMPVBwckFQSXVSW1FwQFlsdlBXd1FUb01wR2BqT1h5Rmh4QUVUaWVSQURLZ2lvVlBPeVhVbFhUOkl3YzxOZ2VNTnVwXFxYV3JkUUZQUXZsUD1Ub3Nlbz5xWGJpV09cXHlFPVBVaVBBQVNnTHR4WExHPVNUQVNBeGo9QFdpeHdYYFhPQXRIbG9JZW9IaUx2eXVvdU10THRUeUpzQXhCWHJAVHFXWE9zRUtvcHVBRVU8dXlPXFxMVHlQQVhtPXRPVVFuZWFORF1LT1l5THlYYnR4dWhtY1lyWE1raFxceWxMb19lcWB0U2VBT0hdbHFVd2lQbmtQd2xIUGdIcmVoWV5wS2hQd0dQSjs8TzxgcVU9dE14VVVFUFdAUmRJVGZZamphb3dUcU1RalhISlNcXE08RXZhcHBUQG1XTUpAaU9WaHlMUUtxXVQ9RXljPVVocU5hXVBKXFxYXFxMdVtEc1FAT1tYUnc8UmJgUGB0U3VlamNlWVhAVU49ckZleHVIbURta11YUkxhWUVsUm1JUF1QZWNoYHJ4bWE/YXJhYUN4dldRW1xcYVpgeWlGQWo/Z3ZWVmReQG1HeVtoaGp4UXZqSXdNVndQR3lYV19FcGpETm5zeV5FaHZFX2Q6UG5rT2FEQV5DbnhFQW9DaF9ld2M7cGJbSVtad2NVP2twR3d4dmNWVlxcT1dhWUdaV3FiR0dealZrQVFdbVhja2Z3VFZmb3ZaVm5aTHdmb0llUz5lQEh0Y3ZzZ1BuPFlxRE94Y3FiZE5tUHh0cXdoc2ZhZz5teU9lZGhxQ0ZrTldxc3B5XUBfVlFySUl1XW5jTEliPl94ZFFeW3l3XmBeWXFiU3hleWdhPk9rVkBmcFZmZU5obXhlU3duXj9fR09rbGZgUXFnS195Sz95akBweHZ3Ykh0SWB5WWFpP0h2Sl53dlF2WW5nQVZvPVhod2NSZUJJTWZsS1RVX2JgcXJGUUM8VUdSV1k9a1ZXQWl2XVg8Q1N5TXljeXdlb0U+P3R0a3NWZ0JUbXRHSVh2S0RUO0RgYXRwYUdRRVZBPWVmb0hAXVRnc3dzQ2ZXR0ViQ0NMSVl0U3dHO3RSYUM/XWhpW1Rmd1NQVWNTUVlaQ3Vsb0VbS1RuT1NUdURQcWZwUVVfWXhbP1VaPWJgeUN1RVRVZWN0Y3JzYVdJR2hQVVZkQ1hvW0RuO0dUb2Y9QVZCY1lSR2dhYVlic3Z0PVVCdVZJT2VaS2dHbWhIUXJdXXVtc2lmeVRQV3RuZXlaS3lkbUhqb1dSQXNTUUhld0RTPUhqXUM+cWRIW1hISWdrd1RHdXZJX3NnWURnYWJTc2lMWXJiXUljW3VaVXVDZUdOXUlueXlqaVZuTXVKaWJxXUU+PXNIW3RoUURYZ1RcXHFoTndUVm1HZG9TaUtzRF1ERF1VT2tzTz1mWDtYdklkYlV3Umlpc0NFdj90RUFTP2VIW0VIaU95W21jRT9oWTtld0tDclt4O0VDcFVFYUl0Uk1VZU1JQHdGPUd1cUlkcmlYbUFpSG91Ql1VRWt2Ym9EYF1iRGV1XlVIT3N4d0tTb2dWRV9HTlFiQkFkdU1ZUTtZX11YYnFCZVtGRllHRj10WGd4cnlZcEFGRG9pZElSSGdVZj91WEdnXVdndUdpZ11VUlFycDt1PU1IWUlYeGNJYW1zcUVsPHVSPFBNd3R3Tk1xTllNQj9cXGFJaXF2Ym94aGtud0RPdl1ecjphXFxbV2hFeHNuX2NkUW9ATmddb3JMUG5DcHRFP3dKcWk6YWRgP2dqWFxcQm9sOkBkSmlzW3ZlbF5wSz5dVHBjSUhob1Nab1hKT2h3W1dnc2VzdUJmRWddPXV1VVk9cVhaV1ZZTVNaRUNIV0hxZVg8U3VeRXV2WVg7QUZRUUNdXUZsXVNOcUlPPUlMUXdoSXdab2VxRW9PcVZZQFRUcHJXQU5xWXN1eE5BQFdqbHB1YVh5dG1YTVJrZHBJXUtcXExUQD1QZFxcU3hISlNYTmh1bEZZUW10d0poV0k8UXN1UlVwd21cXHJRREx5dU1nTXY+QHBTQHBmdFJpVW5pVFY6dVJSaWw8bFJZPHdsdFNWaUxoSEtEQHZWaVNgRE9mYVR2QXN5TXVLbVFVaHZxbFF1TFdAcWxyYFJkZFJLSW1eUVlBYVh4ZFBcXFR1VmxrdE1ZbXlQQWB4Uml2UlVvTHhLbUFOYWxMYHFWYGVURElPO01ZXFxIb1FpWW5Na0hMTnFoeWxVSlxcdFNedUtKSU1LQVlbcXVmTXJ4QVhmeEp5WHhlYFJQcXhPaW9ybEpXXVhFSFh3XFxsSnFyPVh3TjxUPmBuRlBrbEh2XkxUZF1rdml1Oll3bGhXa1R5RHBMU1VWVXFRQ0F1VFRsaVBvcHVvVEhOU1F5UnRzPklxS1lLaFROUU1zZUFqb2FsclF2YklzbE1wPVxcb2pMVU1EdURReW1hb2lRdWxtUE1FTHdocHVwbG5JdnlwUGBYbENETT5MWUBgcmRxdG95bkBNTEZUVVVQb1xcVVdSXFxXTWV0T0FvRWV3TElVY3RSd0B0XUVSR0BYdHFLdUhRV3FqV0xxWmBMVFVPVHVzbUhQY1lrP0ROPXVUXFxhWFNlTE51S3J0dGZAa0l1blVUWENNdFl5UlVRcGxYd2BYdj1pWHBwdUxtUlVxd1RNbVtdcXhoTEVsdD5sTmlAcVE9UV9sUkw8TmdlcmhoWHdBcnlBTD1pd11JeFlUVXloajtwb3FYUG1VZ0hHXFxnYW5mV2ZGPmhyQXd0d3lbWXM8VnVHWGhTR3hlUGpNXmV4blxcdmFiSE5qVGZmRll3RE5yZUBxb2hlSFdtb1dgXVBcXGdmcV1Ja3h4XFw/dmtubmNcXGdpdXBvdkloTWFaT0lraklkVnF0dj9lZm5oZWBpPU9peFZ1ZVZvcHhqSk91TllgW1dcXGpYXFxTTmtlcXJRX3BVZ2hqTmlOUXRwR1xcQ0llX0lhYllzQHd3QndcXExgeE8/cmBxWmk/Y0BXc1dgXkBmam9nZXBwamtJcG5Ya0tQbmRHYWRHaWRvY0U+bT9GamZfYllmXFxcXD9wXUhpZU5xV2dnZUl1Q0FuaGlad2FlcFlua2dlRnlqdk9odV9bR1FrcGlvU05hP25kaXByVUZqY1ZcXHBRbmd3XVI/XVdGZVd4YD5pX0hAdEF3ZGJueTx4X19PYEZ5Z2dxdWpBdEpoYWlBblNBcz14d3RwXmFZbmxvbG4/ZVlRdEFebUp2d0Q/a1xcUWxdeHFNUGNgX3NqVl1ndnJlT3NJT2twUF5WeV5bVndgT1tnd21McWldTm1aQGhCQXJpUF1PPltASGRtWVp5aXJbTm48WXBlTmZvbnNvXl1kbmZJWXVYd2tFQWNVeW5eQWBdVmV5WXVsUG9nQW47P1xcSz9tdF5ncF5qWEd4Zj55c2Zac2d1PWBzZWJfYUlFU1NKY1dld3RtQ3JFQ2ZnRVJhcUVOQ2hCO2ZeSXZ4WUw9UFNdPXlLWG1HZU1ZTG1yVFNCcExfYFVBbG1YbVhsVVRYRW5eRXNTbW1meVJFWHNERXdlbHZRcWxRYVhAQHRqPHBrVFlrRFNOcXhQUWpsdXNpVEpFTFhRXFxSd2BzUGFTVVlKd1BqZGVzX1FzS2BqQElqX0R1Rm1KbVBMbWxsaDxTU1BLVjxXW2VPYWFUTkB3TGx0dj1xZEBPT0hyYzxLPmh1aFBQPUFwU1VSUF1tYklWU3VybERMcXBLdWFWbGlWPklvT3hKeEx5R1hPaHF0PVFQQlFWSXRSamRWP11QRlBQQ3l2c11ZQl1SWEFzUEx5c1FUXk11TFVPRE11ZURQPVVQcEhzRlV4OlhKYGhObEVZS3lrcVFMUUhTRXVyXmFYX1hKSF1VeXh0Z01SQ1h0anVvP0VRV01MW2FSU2lraWRvZUxzVWR1V0VNdGhZWnlRW3F3eEhUW3RPdTxWR3hxYmBxcDxPUUFXT2VZSUl3XlR2YEhyTnlQO0VLaERMaVRxY1hMcTxOWGVqc0VLc2VUO01ZQTxvc211ZkBVQHR4VU1KWWFNRnV2VmFqVWVsdl14WGBuY3VUaFR4Qlxcd3h0dkNpdUBIc1FVUTptc0p5VVZYTE9lVUFMbWRhWV1UTW91cUVFeFdgeEs9UVFMeUdBeWlIUFxceE9mXXRHPmNKd2BneHdeZl1tSWRKd2dYaXliWF1fXlxcXXhdd1hvb3ZmSmB2Z1FrbFdyaHFgc3hxVGhkX0F1WEhvdGF1eHF2VlBzPmZYUUVHX1lHeXVqR1dxYUNPeUU+V1hbd3VFd3lzTUhzQUNhd1lmc0lpcXZXaVdwV0dvR1ltcXdBZWg7X1hxR1N5W1lRVVc8a0ZhVUdtdWhxZVlFO3hkd2JEVURkV1Y8T1lqbXdjXXJMP1RwdXdGX3NuV3VtaWlhQUlueUJbYVVieXhcXHl5YGNTTG1IeHNJbndZTHdmPW9iX2t0eGdVSldUQl1UdEl2S2tERE1JQ01WWkNIPFdXRjt2WGV1T0dlXlFlTHdpa11Ia0NmclVYdV9EZ29DW09JeXVoX0l5YltlRWhxcnlRP013VGV4SXVOYnVtdjxzT2l3eV11Tz5pZT9vTlhwbkZiXWl5a3l2QHBuTT9eYlFiY09wXUBwTV93T0laXFxpXXRWcEdJdT1QZGJIZk14Y3hYYXQ/YVdQWnN3dz54YUR2djx3cVF2eWtecGlBcl9AZmRZeWZveHNhY3RXX3V2Z0JQbXF2bUtfWk1BclpXWnlBdkNQbXVZZFxcQWJacF1aTmdYd3J5WGF4dmE+d2ZZcGNaZ2VtPnV4aXVbR2lZbnV3UXU8YWlKbnM/XFxVTnBxSGdqZndocVtiYWhiQHhDR2JIVmtrX25UUGVpb2JmeWNVZmBYbmF4aWRsd2lUSGptaGVGP3N3PnFXWHhUV3lnUWJ1cFp0WXBncXBrd3dmV3ZjSFpjQXdbaXVNaXliXm1FZnloX3l5WHNJSW9zWGRKZnh2cV0+eWFSX1pWeHlcXGJTP0ViQXdzXXddd3ZjT0ZvTWh3U1VSYWd5Q1lkaVR3QUJ1QUVHV0Z1U0lHb0VrS1lJR0ZZVVlddXdgdXdYb0d1QUZWV2tHd3F5ZmJAcXJyaWZqP3NZcHU9QF9db249Z1tRQGx0UWJRTlpEZlxcRldlXFx5cXV3WzxwdV4+bHZReFxcWXc8d1xcPFZ4UlBuPXl4aU5bQ05nQl5pck9wd0duRWZ5eVdudHF3Omd3RWZaU3BpX0dcXDw/YFFueFY/d3lnbTxOWl5xeWFHcHh4aU1wa19PaHFZcld4XFx0QHQ/QHZBQVxcZXFfclFxdj51eUB0eWFgV3l5Onh2bXlzWHd5WWZbTVd4b1dtSWd2b0U6O0I6TVRLV0RLV2dKO2VaMTo=</Image></Text-field></Input></Group><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/><Text-field/></Worksheet>