diff --git a/internal/compiler/wasm/opa/opa.go b/internal/compiler/wasm/opa/opa.go index 4d1e10c3c4..8f60b3e065 100644 --- a/internal/compiler/wasm/opa/opa.go +++ b/internal/compiler/wasm/opa/opa.go @@ -22,4 +22,4 @@ func Bytes() ([]byte, error) { return ioutil.ReadAll(gr) } -var gzipped = []byte("\x1F\x8B\x08\x00\x00\x00\x00\x00\x00\xFF\xCC\x5A\x5D\x8C\x64\xD7\x51\xAE\x3A\xE7\xDC\xDB\xB7\xFB\xF4\x9D\xE9\xB5\xBD\xF6\xC6\xE3\x9F\xBA\xD7\x76\xB2\x9B\xDD\x75\x9C\x38\x1E\xC7\xCE\x8F\xE7\x0C\x9E\xD9\x9D\x6C\x44\x2C\xD9\x80\x58\x81\x7B\xDB\x3B\xBD\xBB\xD3\x33\xD3\xB3\x9E\xE9\xF5\x8F\x34\x9A\x5E\x61\x45\x18\x11\xC1\x43\x04\x4A\x78\x00\x67\x23\x11\x84\x64\x40\x04\xB0\x2C\x7E\x82\x14\x78\xE6\x81\x47\x90\x10\x91\xCC\x03\x4F\xBC\xF0\x08\x41\x55\xE7\xDC\x9F\xFE\x19\xFF\xBC\x31\x23\xF5\xED\x7B\x7E\xEA\x54\x7D\x55\xA7\xAA\xCE\xE9\x82\xDE\xC1\x2E\x02\x00\xFE\xEA\x89\x2B\x6A\x3C\xC6\xF1\x15\x1C\xC3\x15\x80\x2B\xC8\xDF\xD5\xF8\x88\x3F\x0F\x0F\xA5\x1D\x8F\xF8\xE3\xF0\x0A\xF0\x1B\x77\xE0\xA1\x8C\x19\xC3\x15\x3D\x2E\x3E\x71\x7C\xC5\x8C\xFD\x93\xE9\x1D\xC9\xE7\xA1\x7A\x58\xE9\xFE\xF0\xB5\x78\xB7\xBF\xBB\xB7\xFF\xA6\x02\x79\x6B\xEE\xDD\xEC\x75\x7B\xAF\xEC\xED\x8F\x00\xF5\xFA\x9A\xD2\xCC\x88\x01\xFE\xD3\x5A\xEB\x48\xBE\x20\x20\xEA\xB8\xA1\x13\xDD\x6C\x81\xC6\x44\x27\xD6\x5A\x80\xB6\x4E\x65\x90\xD6\x0B\xC8\x9F\xED\xC5\x0E\x68\xD0\x60\x22\xBC\x89\x88\xF1\x92\x19\xA3\x7B\xE7\x6D\x63\xC7\x50\x3C\x6E\x27\xFC\xF9\xFB\x89\x6D\xBC\x65\x2F\x9C\xE8\x76\x5F\xEF\x1D\xEC\x76\xAF\xF6\x76\x76\xBA\x57\x47\x7B\xFB\x07\x80\xB6\xDB\xBD\xD1\xEF\xDD\xEC\xBE\xD2\x3B\xE8\x6B\x6C\x77\xBB\x9B\x07\x7B\xDD\x1B\xBD\xE1\xE6\x4E\x5F\xAB\x56\xB7\xBB\xD9\x1B\xF5\xBA\xFD\xE1\xA6\xD6\x2D\xE6\x7C\xB7\xB7\xB3\xB3\x77\x15\x54\xC2\x2F\xD7\xF6\xFB\x7D\xD0\xF7\xF0\xD7\xD7\x7A\x3B\xB7\xFA\xDD\xEB\xFD\x51\x77\xEF\x95\x41\xFF\xEA\x08\xCC\x89\xAA\xF9\xEA\xDE\xEE\xCD\xDE\x7E\x1F\xA2\x05\x6E\xF3\x03\x78\x2C\xC4\xF7\x4F\xCE\xED\xED\xEF\xF7\xDE\xEC\x0E\x7B\xA3\xAD\xD7\xFA\xD0\xB8\x7B\x4E\x27\x24\xE9\x44\x2B\x34\x4F\x56\xEF\x5B\xA3\xFE\x7E\xB1\x7E\xEB\x9E\xA9\x76\x3F\xDD\x2E\x4C\x36\x43\xFB\xBE\xAA\x61\xA7\x3F\xBC\x3E\xBA\x51\x50\x48\xEF\x9D\xE9\xF1\x34\x16\x66\xA7\x1C\x8C\xF6\xB7\x86\xD7\x61\xB1\x33\xDD\x03\x9D\xFB\x66\x70\xE8\x5E\xDB\xD9\xEB\x8D\xE0\xC4\xA9\xD9\x9E\xE1\xAD\xDD\x57\xFA\xFB\x70\xD7\x9C\xAE\xB0\xC4\xDD\x96\xBB\x0E\x46\xFB\xC3\xAB\xBB\x37\xE1\x89\x39\xD4\x3D\x93\xF7\xCC\x21\x11\x04\x3B\xB9\x58\x53\xC3\x76\xFF\xCD\x03\xB8\x57\x50\xF1\xE8\x8B\x52\xEF\xAB\x61\x3F\xDC\x1B\x75\xFB\xAF\xDE\xEA\xED\xC0\xA9\x1A\x78\x32\xEC\x53\x75\x4A\xD2\x72\x7F\x4D\xED\xAF\xEC\xED\xED\xF4\x7B\x43\x58\xAA\xA9\x6C\x6B\x38\x82\x07\x16\x6B\x64\x04\x8A\x07\x6B\xB8\x05\x39\x1F\x12\x0B\x1B\xDE\xDA\xD9\x81\x87\x45\xE4\x82\x1A\x2D\xF8\x0E\x06\x4A\xC8\x65\x9D\x5A\x83\xA7\x97\xB7\x02\x48\x4C\xE9\x91\x93\xD5\x4B\x77\xD4\xDF\xDF\xDD\x1A\xF6\x46\xFD\x4D\x78\xB4\x18\xB4\xD3\x1F\xC2\xE7\x3A\xDD\x6E\x85\xC1\xF5\xFD\xBD\xD7\xE1\xB1\x66\xD9\x00\x9F\xBE\xAB\xEA\x7C\x7D\x6B\x74\xA3\x7B\xB5\x77\x13\x3E\xD3\xAA\xA4\x87\xD3\x27\x67\x04\xEF\x1E\xF4\x47\x70\xA6\x53\xCD\xEC\xDD\xBC\xD9\x1F\x6E\xC2\x67\x6B\x68\x1F\xB0\x23\x38\x5B\x87\x51\xAC\xF2\xDC\x7D\x9E\x9D\xD0\xD6\xDF\xE9\xEF\x76\xFD\xCE\x3B\x7F\xA2\x3E\x76\x78\xD0\xDF\x1F\xC1\xE3\x85\x24\x6C\x12\x9F\x17\xB4\xB6\x0E\x36\xB7\xAE\x6F\x8D\xE0\x0B\xE1\xED\xE0\x66\xEF\x6A\x1F\x9E\x6C\xFA\xB7\x1B\xFD\x37\xE0\x8B\xA2\xE2\xC1\xC1\xDE\xB0\xBB\xD3\x7F\xA3\xBB\x77\xED\x1A\xB3\xFB\xD4\xBD\x13\xAD\xFB\xFD\xDD\xDE\xD6\x90\x51\x5C\xEE\x4C\x74\xF4\xF7\xAE\xC1\xD3\xD3\x63\x7B\x9B\xDD\xDE\x68\x6F\x17\xBE\x74\x6A\xB6\x43\xD8\x39\x80\x67\x3E\x35\xDB\x75\x6B\xB8\x75\x75\x6F\xB3\x0F\xCF\xCE\x99\x16\x36\xC4\x97\xE7\x74\x05\xF5\x7E\xE5\xC4\x4C\x17\x7C\x75\xB2\x6D\x6B\xB8\x35\x82\xAF\xDD\x55\xB6\xDD\xEC\xED\x1F\x78\x53\x7C\xEE\x9E\xA9\x46\x6F\x3F\x2B\x27\xA7\x9A\x03\x1B\x6E\x7A\xB8\xB7\x8E\xD5\xE9\xE1\xC1\x26\x9E\x5F\x98\x6C\x87\xB5\xD6\x7F\xAE\xAF\x29\xB0\x8B\x40\xE0\x3A\xAF\x39\x1C\xAC\x80\xEB\x8C\xAC\x02\xBB\x0C\x6A\x45\xAD\x10\x9C\x56\x26\x87\xB5\x14\xB4\x7C\x07\xC2\xCE\xB7\x6E\xDF\xBE\x0D\x6B\xA9\xE2\xF7\x24\x87\x14\xAC\x75\xB0\x68\x65\xA8\xFD\x27\x13\xEB\xB1\x3A\xD4\x63\x8E\x4D\xEA\xC8\x8D\x09\x08\xF7\x1D\x5C\x20\x5C\xCA\x14\x13\x5C\x4B\x81\x70\x2D\x05\x37\xCE\x14\xC1\x79\x80\x5C\x13\xF2\xC3\x6C\xA4\xE0\x30\x53\x64\x48\xF3\x57\xE0\xF1\xD3\xFF\xA4\xDD\x78\x90\x6B\x17\x5D\x4A\x81\xDF\x16\xE2\x16\x28\x6D\x9A\x2D\xBF\x3E\xE1\x69\x65\xB6\x17\xAD\xBB\xFD\xF6\xED\xDB\xD0\xB9\xCD\xAC\x0A\x73\x78\x1E\xD0\xAF\x87\x6B\xA9\x26\x70\xC9\xE0\xAC\x86\x2C\x22\xE5\x7E\x86\xAF\xAE\xA5\xCA\x8D\x29\x22\xF4\xCD\x79\xBC\x49\x11\xC5\x57\x97\xBC\x54\x09\x53\x95\x0F\x93\x2B\x8F\x88\x26\x45\x7A\x63\xA9\xF3\x67\xBC\x40\xAE\xD2\xD8\x4B\xE3\xCC\xE0\xB4\x82\x1C\x08\xC3\x37\xDC\x48\x63\x46\xE0\xD2\xA2\x55\x2B\x42\x26\x6F\x78\xDC\x12\x6A\x50\xB2\x91\x37\x97\x72\xC5\x88\xA8\x77\xB3\x96\x2C\x9F\x59\x67\x32\xBD\x8A\x59\x9B\x92\xCC\xE8\x95\x3A\x0C\xD4\x5E\x1D\x1F\xE6\x29\x99\x77\x2F\xA7\x50\xAC\x46\x9A\x3F\x33\x45\x29\xD9\xA7\x14\xBC\x94\x62\x5B\xD9\xF0\x72\x39\x45\x4B\xAA\xE0\xC6\x8F\xF4\xFA\xE3\x55\xB1\xDD\xB4\xA4\x5C\xD9\x92\x26\x96\xDA\xD4\xBA\x9C\x22\x69\xE6\x44\x53\x7B\x15\x0F\xB3\xB6\xA0\xC5\x6B\x98\x36\xEB\x7A\x4C\x4D\x4A\xA8\xB1\xC1\xE8\x30\xC7\x67\x34\xBC\x9F\xC5\x6D\xB4\x32\xEE\x8C\x86\xAC\x5D\xA0\x8A\x84\x67\x75\x92\xC5\xD4\x7E\x3F\x8B\xAC\x40\x5C\x41\x2B\x90\xB5\x09\xCF\xE8\x24\x4F\x5F\x4C\x91\xDA\x94\xFE\x02\x23\x4E\xD8\xF9\x1D\xE6\x68\xD1\x92\xB2\x4F\x7E\x72\x3B\xB4\xA7\x11\xC7\x1E\x37\x82\xA7\x58\x73\xBF\xC4\x70\x89\x79\xFC\xD0\xE9\xD1\xE0\xB4\x32\x99\x62\xE2\x2B\x88\x47\xAC\x97\xF3\x00\x4E\x5F\x60\xC3\x3C\x0F\xC8\x0F\xE6\x49\xAD\xC2\x8B\xAC\x19\xA1\xF1\xCB\x05\x05\x55\x50\x58\xB4\x0E\xEC\xB7\x51\x71\x4A\xE6\x59\x5C\x13\x93\x14\x93\x56\x2E\x5E\xE7\xB9\x2E\xBA\xC0\x20\x04\xFA\xE8\xE9\xA3\xA7\xAF\x99\x3E\x92\x0E\xF4\xD1\xD3\xD7\x15\xFD\x4F\xBC\xF9\x5E\x46\x35\x96\x6F\x19\x94\x26\x23\x5B\x8D\xCD\x03\xD6\x52\x3D\x45\x27\xD3\x42\x26\x03\xD2\x42\x32\x85\xB6\xB1\x96\x20\x45\x4F\x73\x8D\xCD\x07\xC4\xBA\x18\xAD\x1B\xE8\x25\x0D\x54\x4B\xB1\x94\x88\xB5\x26\x86\xE7\x55\x95\xAC\x05\xB8\x4E\x2B\x58\xF4\x0C\xB2\xC8\xAB\x78\xF8\x11\xA8\xCA\x68\xFB\x13\x54\x6A\x8C\x47\x85\x0A\x05\xD7\x02\x59\xED\x91\xD5\x8C\xAC\x62\x3E\x70\x8A\x0F\x7E\x84\xB5\x0C\xAF\xC5\xFE\xC4\xAF\xE5\xF7\x2E\x99\x6A\xAD\x12\x2C\x2F\x10\x03\xFB\x61\x10\xA1\x40\xA4\xAD\x87\x26\x20\xD3\xF6\x18\x4D\x8A\x4C\xCA\x9E\x47\x1C\x17\x86\x1B\x94\x20\x7A\x74\x38\xC8\xC0\xBB\x02\x4C\xC1\x92\x17\xB9\x21\x93\x93\xF0\x34\xF6\x32\xAA\x71\xC0\x5A\xC4\x46\x67\xD6\x83\x22\x91\x11\x40\x42\x8F\x00\xCF\x0A\x82\xD4\x2D\x86\x47\xEA\x15\x52\xBC\x5A\xDD\x58\x48\xD9\x45\xF0\x5E\x79\x93\x3F\xAE\x2E\xD9\xEF\xA2\xC6\xB1\x3A\x54\x47\xC1\x49\xD6\x9C\xAD\x77\x97\x40\xC0\xBB\x58\x97\xBB\xDA\x8D\x49\xCB\xCE\xCE\xCD\x26\x69\x32\xDE\x51\x9E\xD1\x49\xCD\x9F\xFA\x9D\x6F\x28\x7A\x3F\xD3\x0C\x11\xEB\xE4\xFD\xCC\x58\x99\x5B\x4C\xCB\xA0\x8D\xEC\x07\x80\x7D\x2F\xEF\x89\x98\x6D\x23\xA2\x58\xFC\x80\x7D\x51\x40\xF8\x98\x2E\x18\x8E\x77\xC1\x20\x2E\xD8\x1B\xF1\x7F\x60\x6C\x24\x38\xE1\x91\x1A\xFB\xDD\xCF\xE0\x04\x8C\x3C\xD1\xDC\x2C\xE5\x11\xCB\x1D\xBD\x9B\xC5\xDE\x2B\x37\x9C\xC9\xA2\x55\xCC\x12\xD2\x59\x53\xAD\x88\x5F\x6E\x95\x38\x25\xEC\x97\x2D\x35\xDF\x7D\x29\x05\xB2\xD4\xA8\xFC\x70\xE1\xA4\x23\x71\xA0\xAD\xD0\x29\x7E\xB9\x55\xFA\xE5\xA8\xE6\x97\x5B\xBC\x8F\xB4\xA5\x56\xE9\x97\x5B\xA9\xB2\x94\x50\x7C\x39\x55\x14\x31\x2F\x11\xB1\x75\x67\x49\xE9\x97\x9B\xEC\x97\xA9\xC5\x2E\x95\x83\x27\xA9\x8D\x25\xFB\xEF\x06\xD3\x31\x41\xE7\x77\xC5\x8A\x55\xB1\x6F\xFD\x7B\xAE\x59\x58\x43\x8A\x1F\x11\x19\x8A\x36\x96\xF2\x58\xE2\x90\x33\x2C\x2C\x64\x89\x5E\xA1\x06\x33\x97\x38\x3D\xCA\x9B\x03\xF1\x4D\xCE\x0C\xF2\x16\x37\xCA\x7B\xE0\xCF\xA6\xCA\x41\xD6\x76\x90\xA5\x95\xE1\x04\xF0\x2D\xD3\x6C\x94\x33\xB2\x05\xBD\x42\x96\x5F\x17\x2A\x4F\x66\x99\x09\x9B\x82\x65\x0A\xB6\xD4\x9B\xF5\x00\x5A\x9E\x96\x56\xAD\xE2\x93\x5A\x35\x8A\xAC\x8C\x29\x9A\x58\xD2\x6C\x2B\x1B\x48\xB4\x39\x26\xB6\x2B\x96\x29\x71\x38\xC8\x13\x8A\x37\x64\x5B\x18\x12\x4F\x5D\x8A\x6F\xD9\x93\x31\xE3\xF9\x82\x77\xEB\xCA\x25\x83\xBC\x79\x5A\x49\xFE\xB2\xC0\xFA\x7A\x8B\x49\xA9\x15\xE2\x46\xA7\x36\x0A\xF0\x12\x97\x64\x0B\x0E\xB3\xA6\x5E\xA1\x44\xD8\x1A\x94\xA3\x69\x81\xF5\xB7\x40\x4D\x5E\xBB\x29\x34\x4F\x2B\xF0\x1C\xF0\x62\xD9\x82\xA5\x05\x3F\xD4\x92\x2A\x57\xD0\x6C\xEF\x81\x0F\xFD\x31\xF8\xD0\x9F\x90\x0F\x5D\xE7\x43\x7B\xA4\x27\x58\xD1\x61\x9A\x65\x13\x73\xC8\x68\x5D\x5A\xB2\xFF\x13\xA1\xE5\x38\x8B\x85\xA3\x96\x6D\x39\xE3\x7C\xC4\xD6\xB4\x44\xAA\x4E\xE7\xD7\x04\x7F\xE3\xA2\x67\x01\xC8\x90\x5A\x56\x6D\x32\xAB\xF0\xB4\x32\xC1\x72\x24\x1B\x32\xAE\x3D\xE0\xE9\xA3\x65\x25\xA8\x8E\xFC\xBC\x0C\xD5\x0A\x19\x06\x20\xF2\x00\x88\x3F\x34\x2C\x6D\xEC\x20\xE3\xF0\x86\xA4\x06\x14\xB3\xB8\x6A\x70\x46\xC1\xD3\x32\x3F\x11\x36\x58\x56\x4D\x51\x29\x28\xCF\xCB\x55\x85\x89\x22\xE4\xE5\x22\xF1\xEA\x9C\x84\x95\x56\xDC\x10\x53\x74\x33\xCD\x62\x8B\xCC\x6B\x96\x08\x5B\x19\x6F\x25\x3D\xC8\xE2\xB0\x77\xD8\x53\x90\x12\xF4\x73\x4E\x69\x29\x61\x2E\x46\xAE\x45\x7A\x29\x57\x5E\x36\x5D\xC8\xC6\x2A\xAC\x89\x15\xE4\x81\x8F\x2F\x4F\x5C\x89\x12\x13\x54\xA2\x58\x8A\x44\x15\xCB\x0A\x4A\x05\x68\x52\xEF\x3E\xAD\x99\x1D\xFD\x65\x04\x99\x9A\xA3\x70\x33\xC8\x15\x69\x61\x8D\x9A\xCB\xCA\x04\x1A\x2C\x4E\x92\x37\x78\x1D\xD9\x0B\x62\x66\x02\x3C\xB8\x24\x6B\x39\x14\x7F\x81\xDE\x59\x28\xAF\x9F\xCC\x4A\x83\xA4\xEB\x3E\xA5\x61\x62\x26\x6F\x86\xC8\xEA\x03\x68\x1E\x91\x1A\x64\xB1\xF7\x4E\x0E\x2F\xA6\x40\xAD\x4C\x51\x92\xA1\x5E\xA1\x98\x59\x1F\xB8\x37\x0A\xD1\xC1\x03\xE1\x24\x7C\x53\x41\xA8\x51\x10\x92\x75\xB2\x98\x94\x7B\x63\x20\x81\x72\x3C\xC8\x50\x4E\x0C\x99\xA6\x86\x83\xAF\x73\xBC\xF5\xEB\x71\x48\x4A\x32\xB4\x14\x93\x15\xA8\x08\x79\xB2\x97\x39\xB8\x06\xE3\xB7\xC5\x37\x53\xA4\x16\x63\xDE\xF2\x11\x1F\xC5\xDB\x1A\xFB\x6D\x44\x33\x11\xE1\x6B\xB9\x0F\xD6\x37\x26\xBB\x69\x31\x34\x0F\x1B\x9B\x4F\xA6\x5D\x92\xA1\x43\xCE\xF0\x79\x83\x00\x61\x6D\x77\x4A\xC4\x41\x32\xCC\x86\x38\xE9\xA0\xE1\x60\x78\xCC\x36\x16\x5B\x33\xCC\x91\x23\x5C\x91\xB4\x38\xB8\x60\xFF\xB7\xE0\x8E\x93\xA3\xF1\x20\xC7\x70\x64\xF2\x40\x2F\xC4\x00\x00\xA8\x2A\x02\x8B\xF6\xFF\x8B\x28\xF5\x34\xA6\xC8\xFD\x93\xDC\x84\x34\x38\xD0\x35\x39\x16\x59\x94\x09\x6E\x7E\x82\x98\xDD\x28\x73\x87\x69\x4A\x38\x49\x09\x73\x95\x81\x8F\x84\x58\x52\x52\xA5\xFB\xB5\x65\x4A\xC6\xCF\x33\xDA\xA7\x68\x67\x75\x52\xA6\x6C\x27\xF9\xB4\x81\x61\x63\x81\x43\xF6\x6C\x60\x1F\xE0\xD6\x24\xB4\x22\xEF\x47\x43\xE8\x14\x77\xA2\xEF\xEC\x54\x9D\xBC\x15\xD1\x6F\x45\xB4\x0F\x4E\x75\x3E\x23\x9D\x6F\x29\xDF\xFB\x08\xF7\xB6\x43\xAF\xB8\x2C\xC3\x1E\x92\xE9\x2A\x5E\x25\x91\xD4\x53\x55\x63\xD0\x77\x42\xE7\x4F\x7D\x26\x40\xE8\x87\x21\x3B\x5F\x43\x68\x7F\x9D\x2D\x85\x44\x98\x76\x8E\xDE\x3F\xE1\x52\x8E\xEC\x9A\xB1\xF2\x4F\xAA\xB2\x09\x27\x9B\xD7\xEB\x1E\x44\xEF\x8A\x70\x50\x28\x3F\xEC\xD5\x49\xCD\x43\x3D\xC4\xF0\xD4\x1C\x6B\x46\xC2\xAC\x80\x17\xAD\x53\x02\x29\x21\x02\x1C\x30\x1F\x20\x21\x82\xC0\xFE\x10\x31\xAA\xA1\xE3\x07\x89\x44\x6D\xC2\x10\x47\xC2\x1D\x03\xC7\x10\x08\x31\x04\xAA\x18\xA2\xC4\xD1\x24\x03\xCE\x81\x82\xB3\xF5\xC9\x62\x66\x1C\x64\x91\x08\x03\x03\xE2\x3C\x9E\xA0\x74\x3C\x2C\x0C\x50\xC4\xC2\x44\x22\xA8\x97\x84\xE7\xE5\x50\x49\x02\x5E\x12\x42\x6F\x15\x49\x29\x4C\xEC\xAD\xA2\x29\xBB\x74\x59\x19\xFB\x53\x16\xA4\x30\x49\xE5\xC1\xD7\x7E\x4F\xB5\x07\x1F\x12\x26\x4C\xB1\x0B\xEB\x21\x10\xEA\x21\xD0\x7C\xFC\x90\x01\x33\x21\xD0\xD4\xE3\x06\xAF\xF3\x51\xA1\xA3\x48\x70\x8B\xD8\xE1\x0D\x52\x42\x88\xFD\x6D\x85\xB6\x90\xB1\xE6\x30\x24\xB6\x05\x87\xA1\xBC\xE7\x36\x1C\x37\xE2\x41\x2E\x51\x33\x21\x6E\x18\x0F\xF2\x66\x11\x37\x1A\xBC\x8B\x5B\x84\x27\xE4\x42\x47\xAE\x6D\x24\x00\x53\x5C\x84\x8E\xC8\x87\x0E\xCD\x21\x38\xB3\x12\x3A\x1A\x14\x95\xF2\xFB\x2C\xDB\x1D\x0A\xAB\x35\x42\xED\x82\x50\x33\x84\x8E\x88\x43\x47\x44\x96\x63\x86\xA5\x26\x3F\x9A\xD4\x0E\xA1\x83\x29\x32\x92\x12\x3D\x4C\xC6\x31\x97\x12\x06\xAC\x41\x56\xA2\x47\x6B\x59\xB2\x64\xB9\x3B\x99\x63\xF8\xF6\x2E\xBF\x2D\x04\x06\xC2\xA5\xD3\x85\xD1\x57\xFB\x19\xBC\xBA\xFD\x46\x0E\x60\xDA\xEF\x21\x6A\x4E\xB4\x74\x75\x15\x62\xBC\x93\x36\xC1\x49\x17\xD9\x87\x18\x80\x9E\xB8\x2A\xF0\xFA\xCE\xB5\x1F\xC1\xC9\x58\xF0\x72\x26\xD3\xB6\x5C\x39\x0A\xC9\x8F\x5F\x39\x12\xDF\xC0\xD9\x26\x13\xD7\x14\x2D\xFB\x43\x26\xB3\x1D\x2D\xCB\x01\x57\xCB\x10\xFB\x30\xE2\x98\x40\x02\xAD\x96\x00\x3E\xC8\xF9\x38\xCE\x68\x21\xC1\xB6\xFD\x46\x75\x8E\x55\xC1\xEF\x4E\x5E\xF9\x29\x3E\x09\x5E\x4A\xB5\xCC\x15\xB7\x22\xE7\x63\xC5\xFA\x57\xC5\xF5\x86\x1B\x2F\x5A\x87\xF6\xFB\x88\x8D\xB0\x5A\x91\x5F\xE6\xAA\x58\x4D\xA2\x3C\x4B\x2F\x46\xEE\x5B\x8B\x3B\x43\xC2\x6D\x8E\x3E\x04\xDB\xE1\xB4\x93\xC7\x4B\x9C\xBE\x15\x99\x2A\x6F\x95\xC0\x56\xF8\x96\x08\x67\xEE\xD4\xC8\x9D\xBA\x45\x89\x7F\x7E\x3D\xD5\x61\x4D\x6A\x88\x3E\xDD\x58\x32\x14\xB3\xB1\x54\xB2\xB8\xC0\x36\xFE\xC2\x80\x0F\xC1\xAE\xB5\x61\xCF\x84\x4B\x00\xF7\x1A\x47\xE0\x7B\x2F\xA5\xE0\x90\x70\xE4\x7E\xE3\xF6\x6D\xF5\x2A\xAF\x8F\x02\x6B\x73\xDD\xB2\x03\x76\xFF\x86\xAF\xBA\x1F\x8F\xFD\xEC\x78\xA3\x4E\x69\xDF\xFA\xEB\x85\x8E\xE4\x20\xDB\xF6\xEE\x70\x71\xC2\x4D\xDB\xD2\x36\x08\x6D\x61\x84\x74\x7F\xD3\x5E\x14\x06\x82\xD5\x48\x77\x6E\xC2\x78\x52\xBC\x63\x38\x99\x57\xFE\x10\xCD\xE9\xAC\xBF\xF8\x71\x9D\x41\x5E\x66\x5B\x6C\x17\xDA\x5E\x46\x1D\xB6\x72\x27\xC7\xFA\x12\xB2\xAB\x3B\x83\xC2\x0B\x49\x12\x7E\x0E\xA0\xF3\xE7\xC5\x59\x4C\xC9\x1E\x13\xCB\x60\x52\xC5\xE4\xD2\x89\xDA\x6F\x21\xC7\x2B\x94\xEC\xBE\x62\x53\x05\x36\x9D\xB9\x28\x67\x7B\x24\xC5\x64\xFF\xC2\x93\xF5\x8B\x8A\xEF\x3A\x07\x58\xB5\xFA\x06\x35\x35\x0C\xA4\x55\xD7\x5A\x85\xB6\x33\xE2\xD9\x7C\xE2\x60\xFF\xDB\x88\x75\x05\x11\x97\x55\xE2\x53\x25\x7F\x9D\x77\xFE\x42\xA0\x15\x6C\xDC\xCF\x53\x34\x09\x85\xBF\x8B\xCA\x94\xF5\x06\x2F\xBA\x7B\x62\x76\x66\x40\xAA\x8D\xC5\x38\x31\xAF\x02\xB1\xA2\xBB\x92\x70\x0A\xF0\x80\xB4\x99\x42\x5A\x1D\x87\xB4\xF1\x48\xB7\xB5\xAD\xD4\xEB\x73\x2F\x96\x2F\x24\xCF\x5E\x21\x39\xEB\xB3\x92\xFA\xF1\x0B\x25\xD0\x15\xF7\x45\x0E\x49\xD1\x76\xAE\x29\x18\x80\xF1\xA7\x9E\x8F\xC1\x4F\x2E\xD3\xE4\xC4\x61\xC2\x89\x93\xCC\x86\xBF\xF4\x08\x9C\xE5\x15\x53\xC5\x59\x8B\xC5\xB6\x05\xBA\xA4\x1C\xED\x0B\xB8\x1F\xC0\x24\xBA\xBA\xD0\x8B\x66\xEE\x62\xE6\x0E\xBD\x0B\x60\x81\x1A\xEE\xFC\x7A\x0A\xD4\x70\x67\x2F\xC8\xCD\xA6\x9F\xA6\xFC\xB4\xDA\x94\xA0\xBF\x98\x2A\xEB\x0E\xF9\x0E\x3B\x0B\x3D\x21\x23\x4A\x82\x5C\xAC\x4D\x3A\x60\x5E\x65\xBA\x3A\xC3\x36\xD6\x41\xF7\x19\x40\xDB\x45\xFE\x42\xEA\x47\x1A\x63\x39\x45\x17\xBB\x8B\x3D\x9A\xCB\x45\xAE\xE0\x6E\xD8\x25\x8B\x16\xC4\xE9\x4A\xA2\x27\x98\x78\x83\xC8\x23\xD1\x19\x3B\xC4\x73\x00\x79\xEC\xF2\x75\x16\x9A\x62\xF7\xAF\xC0\xE2\xC6\x8E\x2E\xA6\x9A\x62\xF7\x33\x58\x4F\x35\xE9\x92\xA8\xC4\xFB\x6D\x8A\x3C\xF8\x01\x0F\xE9\x8C\xB9\x33\x96\x4E\x36\xEA\xF8\x1C\x80\x7B\x79\x90\xC7\xEE\x9F\xE1\x92\x07\x94\xE9\x2F\xBC\x04\xA6\xF6\x37\xF1\xF2\x51\x7F\x50\x7E\x42\xAD\x05\x0C\x20\xB0\x7A\xD5\x20\x5C\xAC\x7A\x96\x54\xE0\x37\x22\x33\x20\xB5\xCD\x2E\x41\x4D\xB8\x03\x35\xD7\x1D\xA8\x69\x77\x30\x31\x4C\x4F\x0E\x13\xF5\x16\x2B\x4A\x12\x07\xFE\x7A\xA2\x84\x85\x6D\x2B\xF6\xBE\xE2\x3D\xF6\x15\x95\xCB\xEA\xE4\x41\x25\x3A\xA8\xA4\x32\x9C\x28\x6C\x8E\xD9\x9F\xB2\xF8\x5F\xCB\xFE\x3F\x27\x17\xBC\x2F\x0F\xF2\x86\xFB\x17\xB8\xC4\x16\xBA\xF0\x2B\x1A\x8A\x3F\x03\xF5\xBF\x08\x3E\xE2\x2F\x86\x46\xF1\x35\x09\xCF\xA6\x7C\xB6\xFC\x8B\x65\x47\x40\xE8\x2D\x38\x64\xC3\xB2\x2D\x14\x47\x83\xCE\x8F\x02\x26\x2C\x1C\x45\x92\x3B\xD4\xCC\xA5\x10\xB2\xD8\xBE\xD8\x4E\xD9\x70\x3A\x7F\xED\x0F\x6E\xDE\xBD\x74\xFE\xA6\x38\xC6\xD5\x91\xB3\xD3\x0D\xED\xE9\x86\xE6\x74\x43\x8B\x29\xF2\x09\x9E\xD4\x36\x99\x81\x8B\x2E\xA6\xC6\x7D\xF7\x6D\xC9\x54\x5D\xE4\x83\x56\x6A\xBC\x4E\xC3\x3E\x8C\x64\xA2\x99\x9A\x68\x2E\xA6\xDA\xFD\x56\x98\x68\xC2\x44\x3D\x31\xD1\x87\x02\x35\x3B\x51\xB9\xEF\x4C\x4D\x54\x73\x26\xEA\x69\xDE\x1B\xD3\x0D\x9C\x40\xA1\x7D\x08\xCA\xB4\x2E\xE4\x7A\xFC\xE8\x90\xE2\xB3\x4B\x62\xBB\x0A\xC7\xEA\x68\x75\xBC\x8A\xFE\xE0\x7E\x7E\x3D\x57\x4B\x99\x5E\xF5\x79\xBF\x22\xFC\x79\xEF\x16\xE4\x27\x04\x52\xDB\x99\x5A\xF5\x07\x30\xB3\xDA\x3A\x22\x78\x02\xE0\x70\xF5\x85\xC3\xCC\xCC\xA6\x51\x64\x48\x1F\xD9\x9F\xEA\x08\xC7\xEA\x50\xEE\xFB\xC7\xCF\x7B\x83\xF8\xAF\x1F\x17\x5F\x9E\x9B\x58\xF4\xF9\xC2\x8C\x6A\x6B\xD7\xDA\x42\xDA\x94\x47\x13\xC1\xDE\x84\x11\x8F\xAE\xDC\x21\xEE\x71\x2F\x0C\xDE\x7B\x27\x33\x45\xDE\xC4\x49\xBA\xF7\xF8\x77\x78\x4B\x30\xD5\x75\x7F\xDB\xE0\xF3\x2E\x89\x38\xD5\x22\x0D\xB5\x52\xCE\xE4\xD5\x7F\xEF\x7B\xFC\xF7\xFE\x73\x99\xA9\x8D\x99\xCF\x48\x83\xF3\xBC\xC0\xC0\x9D\x77\xB2\x46\x8D\xB3\x1F\xCC\xF0\x13\x93\xA6\xC6\x9D\x77\xB2\xD8\x33\x84\xD6\x61\x96\x14\x57\xD9\x7E\x6C\x53\xD2\xC2\xC8\x9D\xF5\xFC\x46\x3E\x23\x10\x4F\xD5\x74\xE3\x2C\xE1\x29\x11\x35\x99\xA2\x5C\x16\xA2\xFC\x16\xA2\x06\x79\x93\x59\x17\xAF\xDF\x64\x6F\x80\xD4\xDC\xF6\x37\xA6\x92\xC1\xB6\x76\x84\xCB\x81\x7B\x81\x33\x28\x3E\x5F\xF2\x18\xB9\xB0\x49\xA1\xA0\xC2\x5C\xF2\x57\xCD\xEB\xB6\x76\xA4\x8D\xF5\xEA\x8F\x25\x56\x92\xD0\x64\xE7\xBD\x3B\x59\x6C\x29\xB6\x7F\x89\x4A\x8D\xD5\x51\xED\x46\x6D\x3A\xCB\x75\x8F\xAF\x4B\x76\xFB\x8F\xE0\x9F\x1F\xC8\x73\x02\x92\x09\x13\xD4\x4B\x99\x59\x85\x2C\xF2\xA9\xB4\x37\x41\x2D\x37\x6C\xA4\xB7\xC5\x3A\x85\x35\x36\x41\x55\x98\x60\x54\x5E\xFF\xCA\x0D\xA0\xF0\x19\x91\x39\xEA\x7C\xBF\x70\x0E\x84\x9D\xBF\xE7\xEF\x9D\x3B\x72\xCF\x72\x03\x8D\x84\xC1\xCE\x1F\x16\x8E\x89\xF3\x89\xE2\xCC\xD3\xF9\xDB\x70\x71\x6C\xD7\xE5\xB8\xD3\xBA\x20\x41\xCB\x6F\xD6\x54\x32\x19\x20\xD3\xF9\x89\xBF\x16\x90\x4C\x90\xB0\xF3\xC7\x72\x1B\x86\x12\x81\xE5\xFE\x96\x03\xEE\x77\xB4\xD2\x63\x75\x54\xFC\xB0\x4E\xE8\x8E\x38\x39\x6F\x94\xD7\x63\xD5\x6F\xA7\x0B\x09\xA0\xD2\x26\x6A\xC4\x60\x3B\x7F\x10\x7C\x1C\x76\xDE\x29\xBC\x5D\xF1\xCD\x47\x81\x76\xF8\x0D\x69\x3B\x37\x05\xEC\x7C\xE0\xD1\x04\x03\xFF\x13\xDE\xE3\xEB\x69\x4C\x28\xB0\xF3\xF3\x03\x79\x8A\x7B\x05\x32\x15\xEC\x3A\xC0\x8E\x4B\x59\xB4\x0A\xB2\x4F\x0C\xE1\x37\xE4\x24\x26\xBB\xDA\x10\x6E\x67\xC8\x5D\x7C\xD0\x9D\xD8\xF9\x71\xF9\x03\x63\x61\x43\x62\x1E\x35\xD8\xE5\xA2\xCB\xB3\x8B\xDB\x9D\x1F\x14\xCD\x9D\x7F\xF0\xB0\xB7\xD1\xD6\xB5\x20\x3A\x30\x13\x3A\xD0\x5E\x07\x7A\x42\x07\xA6\xD0\x81\xFE\x08\x1D\x2C\x5A\x52\x72\x7C\x34\x13\xDA\xFF\x4D\x2C\xD4\xFF\x47\x13\xEA\x3F\x66\xE9\xE4\xC3\x96\x96\x43\x6B\x98\xE2\xDA\x3E\x91\x0A\xAF\x93\xCC\x69\xC2\xCE\x9F\xCC\xB2\x67\x7F\x11\x71\xFC\x88\xAF\x1D\xA1\xED\x5C\x3D\x7A\xBB\xFA\x7D\xA0\x5D\xDE\xB2\xF1\xE3\x94\xF8\x6D\xDD\x91\x0B\x16\xF9\xA8\x2F\x23\xFE\x97\x06\x61\x3A\x58\xFB\x18\x4A\x01\xE4\x43\x5B\x3B\x3B\xFD\xEB\xBD\x1D\x92\xEA\x2C\x90\x9A\xB2\xD1\xFE\xAD\x3E\x5C\xEB\xED\x1C\xF4\x01\xFE\xAE\x65\x86\xBD\xDD\x3E\xFE\x55\x6B\x1D\xAA\xF2\x4C\x9C\xAD\x96\x54\xB5\x12\x48\x5D\x56\x40\x9A\xB9\x05\x90\xD1\x6C\xFD\x63\x3C\x55\xFE\xD8\xF8\x90\xEA\xC7\x64\x5E\xF1\x63\x73\xB2\xF6\xB1\x35\xBF\xF4\xD1\xCE\xAD\x7C\x6C\x4F\x15\x3E\xA6\xC7\xD5\x3D\x2E\x1C\x53\xF6\xB8\x78\x5C\xD5\x63\x67\xA6\xE8\xF1\xC4\x71\x35\x8F\xF3\xEA\x1A\x7D\x69\xD5\xDD\xC7\x56\x3C\xDE\x73\x5C\x89\xE3\xC9\x63\x2B\x1C\xEF\x9D\x2E\x70\xBC\x6F\xAA\xBE\xF1\xD4\xBC\xF2\xC6\x4F\x4D\x55\x37\xDE\x3F\x5D\xDC\xB8\x34\x5B\xDB\xF8\xC0\x64\x69\xE3\x83\xD3\x95\x8D\x0F\xCD\x14\x36\x3E\x5C\xD6\x35\x52\xBD\xAC\x31\x9B\xAA\x6A\xCC\x67\x8A\x1A\x1F\xA9\xD5\x34\x3E\x3A\xBF\xA4\xF1\xB1\x99\x22\xC6\x4F\x57\x35\x8C\x9F\x99\x53\xC2\x78\xBA\x56\xC1\x78\x66\x7E\x01\xE3\x67\x67\xEA\x17\xCF\x4E\x95\x2F\x9E\x9B\xAE\x5E\x3C\x7F\x5C\xF1\xE2\xE3\xB3\xB5\x8B\x9F\xAB\x15\x61\x3E\x51\x2F\x6D\xFD\x7C\xAD\xA6\xF1\x0B\xF5\x92\xC6\x27\xEB\x15\x8D\x5F\xAC\x0A\x1A\x9F\x9A\x57\xCF\xB8\x7C\x4C\x39\xE3\xD3\x33\xD5\x8C\x5F\x3A\xA6\x98\xF1\x99\x63\x6B\x19\x9F\x3D\xBE\x94\x71\x5E\xB9\xA2\xD7\xE5\x57\x8E\x2D\x64\xFC\xEA\x6C\x1D\xE3\xD7\x66\xCB\x18\x9F\x9B\x53\xC5\xB8\x32\xB7\x88\xD1\xCD\xAF\x61\x5C\x9D\x5B\xC2\xF8\x73\xD3\xAD\xA3\xBD\xED\xFE\xF0\xF9\xF9\x75\x8D\x6B\x53\x65\x8D\xFF\x17\x00\x00\xFF\xFF\x89\x4C\xE4\x2E\x4F\x2F\x00\x00") +var gzipped = []byte("\x1F\x8B\x08\x00\x00\x00\x00\x00\x00\xFF\xCC\x7A\x5D\x8C\x64\xD7\x51\x7F\xD5\x39\xE7\xDE\xBE\xDD\xA7\xEF\x4C\xEF\xC6\x6B\x6F\x3C\xFE\xA8\x7B\x6D\x27\xBB\xD9\x5D\xC7\x89\xE3\x71\x6C\xE7\x1F\xCF\x99\x78\x66\x76\xB2\xD1\x3F\x96\x6C\x40\xAC\x90\x7B\x7B\x77\x7A\x77\xA7\xE7\x6B\x3D\xD3\xEB\x0F\x34\x9A\x5E\x11\x01\x46\x44\x20\x14\x09\x12\x1E\xC0\x6C\x90\x2C\x04\x96\xF8\x0A\x96\x1F\xC0\x12\x28\xBC\xF2\xC0\x23\x91\x10\x11\xE6\x99\x17\x1E\x21\xA8\xEA\x9C\xFB\xD1\x1F\xE3\x8F\x37\x66\xA4\xBE\x7D\xCF\x47\x9D\xAA\x5F\xD5\xA9\xAA\x73\xBA\xA0\x77\xB0\x83\x00\x80\x57\x4F\x5E\x51\xA3\x11\x8E\xAE\xE0\x08\xAE\x00\x5C\x41\xFE\xAE\x46\x47\xFC\x79\x78\x28\xED\x78\xC4\x1F\x87\x57\x80\xDF\xB8\x03\x0F\x65\xCC\x08\x78\x20\x5C\xD1\x23\xFE\xCA\x9F\x38\xBA\x62\x46\xFE\xC9\x44\x8F\xE4\xF3\x50\x3D\xAC\x74\x7F\xF7\xB5\x78\xA7\xBF\xB3\xB7\xFF\xA6\x02\x79\x6B\xEE\xDD\xEA\x75\x7B\x57\xF7\xF6\x87\x80\xFA\xE2\x9A\xD2\xA8\x01\xC0\x00\xFF\x69\xAD\x75\x24\x5F\x10\x51\xC7\x0D\x9D\x68\xDD\x6C\x81\xC6\x44\x27\xB6\x6D\x2D\x40\xAA\xE7\x64\x94\xD6\xF3\xC8\x9F\x69\xE7\x04\x68\xD0\x60\x22\xBC\x85\x88\xF1\x82\x19\xA1\x7B\xFB\x2D\x63\x47\x50\x3C\xEE\x24\xFC\xF9\x07\x89\x6D\xFC\xA9\x5D\x3F\xD1\xED\xBE\xDE\x3B\xD8\xE9\x5E\xEB\x6D\x6F\x77\xAF\x0D\xF7\xF6\x0F\x00\x6D\xB7\x7B\xB3\xDF\xBB\xD5\xBD\xDA\x3B\xE8\x6B\x6C\x77\xBB\x1B\x07\x7B\xDD\x9B\xBD\xDD\x8D\xED\xBE\x56\xAD\x6E\x77\xA3\x37\xEC\x75\xFB\xBB\x1B\x5A\xB7\x98\xF7\x9D\xDE\xF6\xF6\xDE\x35\x50\x09\xBF\x5C\xDF\xEF\xF7\x41\xCF\xF1\xD7\xD7\x7A\xDB\xB7\xFB\xDD\xE1\x9B\xB7\xFA\x60\xEE\xA9\x1A\x6E\xF4\x87\xDD\xBD\xAB\x83\xFE\xB5\x21\x44\x27\xAA\xE6\x6B\x7B\x3B\xB7\x7A\xFB\x7D\x88\x65\xAE\x1F\xC0\x63\xA1\x71\xFF\xF8\xDC\xDE\xFE\x7E\xEF\xCD\xEE\x6E\x6F\xB8\xF9\x5A\x1F\x92\xCF\xCC\xE8\x84\x66\x3A\xD6\x0A\xAD\x53\xD5\xFB\xE6\xB0\xBF\x5F\xAC\x6F\xEF\x99\x68\xF7\xD3\xDB\x73\xE3\xCD\x90\xDE\x57\x35\x6C\xF7\x77\x6F\x0C\x6F\x16\x14\xE6\xEE\x9D\xEA\xF1\x34\xE6\xA7\xA7\x1C\x0C\xF7\x37\x77\x6F\x40\xA7\x33\xD9\x03\x27\xEE\x9B\xC2\xA1\x7B\x7D\x7B\xAF\x37\x84\x93\xA7\xA7\x7B\x76\x6F\xEF\x5C\xED\xEF\xC3\x67\x66\x74\x85\x25\xEE\xB1\xDC\x75\x30\xDC\xDF\xBD\xB6\x73\x0B\xBE\x3C\x83\xBA\x67\xF2\xD4\x0C\x12\x41\xB0\x7B\xE7\x6B\x6A\xD8\xEA\xBF\x79\x00\xF7\x09\x2A\x1E\x7D\xD1\xF2\xE9\x1A\x4C\xD2\xF0\xD9\xFA\x1C\x69\xB9\xBF\xA6\xE0\xAB\x7B\x7B\xDB\xFD\xDE\x2E\x2C\xD4\x94\xB3\xB9\x3B\x84\x07\xE6\x6B\x64\x44\xE8\x07\x6B\x08\x05\x89\x1E\x12\xE3\xDA\xBD\xBD\xBD\x0D\x0F\x8B\x70\x05\x35\x9A\xF7\x1D\x0C\x49\xF7\x60\xF3\x97\xFB\x90\xCD\xD5\x5A\x78\x81\xBC\x53\x6B\xF0\x2B\x3C\xD2\x0A\x00\x31\xED\x47\x4F\x55\x2F\xDD\x61\x7F\x7F\x67\x73\xB7\x37\xEC\x6F\xC0\x63\xC5\xA0\xED\xFE\x2E\x7C\xA9\xD3\xED\x56\xF2\xDF\xD8\xDF\x7B\x1D\x3E\xD7\x2C\x1B\xE0\xF3\x27\xAB\xCE\xD7\x37\x87\x37\xBB\xD7\x7A\xB7\xE0\x4C\xAB\xC2\x03\xCE\x9E\x9A\x82\xA2\x7B\xD0\x1F\xC2\x17\x6A\x3A\x28\xC4\xE8\x0F\x85\xF1\x73\x9D\x8A\x68\xEF\xD6\xAD\xFE\xEE\x06\x9C\xAF\x29\xE1\x80\x5D\xC6\x85\x3A\xE6\x62\xAC\x8F\xDF\xE7\x39\x0D\x6D\xFD\xED\xFE\x4E\xD7\xEF\xD0\x2F\x9E\xA8\x8F\xDD\x3D\xE8\xEF\x0F\xE1\x89\x42\x48\xB6\x94\x27\x05\xDA\xCD\x83\x8D\xCD\x1B\x9B\x43\xF8\x4A\x78\x3B\xB8\xD5\xBB\xD6\x87\xA7\x9A\xFE\xED\x66\xFF\x0D\x58\x94\x5D\x37\x38\xD8\xDB\xED\x6E\xF7\xDF\xE8\xEE\x5D\xBF\xCE\x92\x3C\x7D\xEF\x58\xEB\x7E\x7F\xA7\xB7\xB9\xCB\x00\x7F\xB5\x33\xD6\xD1\xDF\xBB\x0E\xCF\x4C\x8E\xED\x6D\x74\x7B\xC3\xBD\x1D\x78\xF6\xF4\x74\x87\xB0\x73\x00\xCF\x7D\x76\xBA\xEB\xF6\xEE\xE6\xB5\xBD\x8D\x3E\x7C\x6D\xC6\xB4\xB0\x4F\xFE\xDF\x8C\xAE\xA0\xF9\xAF\x9F\x98\xEA\x82\xE7\xC7\xDB\x36\x77\x37\x87\xB0\x74\xB2\x6C\xBB\xD5\xDB\x3F\xF0\x76\xEB\xEE\x99\x68\xF4\xA6\xB5\x7C\x6A\xA2\x39\xB0\xF1\x8D\xC9\xE1\xDE\x70\x5E\x98\x1C\x1E\xCC\x65\x75\x6E\xBC\x1D\xD6\x5A\xBF\xB3\xB6\xA6\xC0\xCE\x03\x81\xEB\xBC\xE6\x70\xB0\x04\xAE\x33\xB4\x0A\x6C\x03\x08\x2E\x00\xD8\x45\x50\x4B\x6A\x89\xE0\x8C\x32\x39\xAC\xA4\xA0\xE5\x3B\x10\x76\x7E\xED\xCE\x9D\x3B\xB0\x92\x2A\x7E\x4F\x72\x48\xC1\x5A\x07\xF3\x56\x86\xDA\x7F\x32\xB1\x1E\xA9\x43\x3D\xE2\x90\xA6\x8E\xDC\x88\x80\x70\xDF\xC1\x1A\xE1\x42\xA6\x98\xE0\x4A\x0A\x84\x2B\x29\xB8\x51\xA6\x64\xA9\x5C\x13\xF2\xC3\xAC\xA7\xE0\x30\x53\x64\x48\xF3\x57\xE0\xF1\x93\xFF\xA4\xDD\x68\x90\x6B\x17\x5D\x4A\x81\xDF\xE6\xE2\x16\x28\x6D\x9A\x2D\xBF\x3E\xE1\x19\x65\xB6\xE6\xAD\xBB\xF3\xD6\x9D\x3B\xD0\xB9\xC3\xAC\x0A\x73\x78\x01\xD0\xAF\x87\x2B\xA9\x26\x70\xC9\xE0\x9C\x86\x2C\x22\xE5\x7E\x86\xAF\xAE\xA4\xCA\x8D\x28\x22\xF4\xCD\x79\xBC\x41\x11\xC5\xD7\x16\xBC\x54\x09\x53\x95\x0F\x93\x2B\x8F\x88\x26\x45\x7A\x7D\xA1\xF3\x97\xBC\x40\xAE\xD2\xD8\x4B\xE3\xCC\xE0\x8C\x82\x1C\x08\xC3\x37\x5C\x4F\x63\x46\xE0\xD2\xBC\x55\x4B\x42\x26\x6F\x78\xDC\x12\x6A\x50\xB2\x9E\x37\x17\x72\xC5\x88\xA8\x77\xB3\x96\x2C\x9F\x59\x67\x32\xBD\x8C\x59\x9B\x92\xCC\xE8\xA5\x3A\x0C\xD4\x5E\x1E\x1D\xE6\x29\x99\x77\x2F\xA7\x50\xAC\x46\x9A\x3F\x33\x45\x29\xD9\xA7\x14\xBC\x9C\x62\x5B\xD9\xF0\x72\x39\x45\x4B\xAA\xE0\xC6\x8F\xF4\xFA\xE3\x55\xB1\xDD\xB4\xA4\x5C\xD9\x92\x26\x96\xDA\xD4\xBA\x9C\x22\x69\xE6\x44\x53\x7B\x19\x0F\xB3\xB6\xA0\xC5\x6B\x98\x36\xEB\x7A\x44\x4D\x4A\xA8\xB1\xCE\xE8\x30\xC7\x67\x35\xBC\x9F\xC5\x6D\xB4\x32\xEE\xAC\x86\xAC\x5D\xA0\x8A\x84\xE7\x74\x92\xC5\xD4\x7E\x3F\x8B\xAC\x40\x5C\x41\x2B\x90\xB5\x09\xCF\xEA\x24\x4F\x5F\x4A\x91\xDA\x94\xFE\x1C\x23\x4E\xD8\xF9\x5D\xE6\x68\xDE\x92\xB2\x4F\x7E\x7A\x3B\xB4\x67\x10\x47\x1E\x37\x82\xA7\x58\x73\xBF\xC0\x70\x89\x79\xBC\xE3\xF4\x70\x70\x46\x99\x4C\x31\xF1\x25\xC4\x23\xD6\xCB\x05\x00\xA7\xD7\xD8\x30\x2F\x00\xF2\x83\x79\x52\xCB\xF0\x12\x6B\x46\x68\xFC\x62\x41\x41\x15\x14\xE6\xAD\x03\xFB\x5D\x54\x9C\xC9\x79\x16\x57\xC4\x24\xC5\xA4\x95\x8B\x57\x79\xAE\x8B\xD6\x18\x84\x40\x1F\x3D\x7D\xF4\xF4\x35\xD3\x47\xD2\x81\x3E\x7A\xFA\xBA\xA2\xFF\xA9\x37\xDF\x2B\xA8\x46\xF2\x2D\x83\xD2\x64\x64\xAB\xB1\x79\xC0\x4A\xAA\x27\xE8\x64\x5A\xC8\x64\x40\x5A\x48\xA6\xD0\x36\xD6\x12\xA4\xE8\x69\xAE\xB0\xF9\x80\x58\x17\xA3\x75\x13\xBD\xA4\x81\x6A\x29\x96\x12\xB1\x56\xC4\xF0\xBC\xAA\x92\x95\x00\xD7\x19\x05\xF3\x9E\x41\x16\x79\x19\x0F\x3F\x06\x55\x19\x6D\xFF\x01\x95\x1A\xE1\x51\xA1\x42\xC1\xB5\x40\x56\x7B\x64\x35\x23\xAB\x98\x0F\x9C\xE0\x83\x1F\x61\x2D\xC3\x6B\xB1\x3F\xF1\x6B\xF9\xBD\x4B\xA6\x5A\xAB\x04\xCB\x0B\xC4\xC0\x7E\x14\x44\x28\x10\x69\xEB\xA1\x09\xC8\xB4\x3D\x46\xE3\x22\x93\xB2\x17\x10\x47\x85\xE1\x06\x25\x88\x1E\x1D\x0E\x32\xF0\xAE\x00\x53\xB0\xE4\x45\x6E\xC8\xE4\x24\x3C\x8D\xBD\x8C\x6A\x14\xB0\x16\xB1\xD1\x99\xD5\xA0\x48\x64\x04\x90\xD0\x23\xC0\xB3\x82\x20\x75\x8B\xE1\x91\x7A\x89\x14\xAF\x56\x37\x16\x52\x76\x1E\xBC\x57\xDE\xE0\x8F\x6B\x0B\xF6\xFB\xA8\x71\xA4\x0E\xD5\x51\x70\x92\x35\x67\xEB\xDD\x25\x10\xF0\x2E\xD6\xE5\xAE\x76\x23\xD2\xB2\xB3\x73\xB3\x41\x9A\x8C\x77\x94\x67\x75\x52\xF3\xA7\x7E\xE7\x1B\x8A\xDE\xCF\x34\x43\xC4\x3A\x79\x3F\x33\x56\xE6\x16\xD3\x32\x68\x23\xFB\x01\x60\xDF\xCB\x7B\x22\x66\xDB\x88\x28\x16\x3F\x60\x5F\x12\x10\x3E\xA1\x0B\x86\xE3\x5D\x30\x88\x0B\xF6\x46\xFC\x1F\x18\x1B\x09\x4E\x78\xA4\x46\x7E\xF7\x33\x38\x01\x23\x4F\x34\x37\x0B\x79\xC4\x72\x47\xEF\x66\xB1\xF7\xCA\x0D\x67\xB2\x68\x19\xB3\x84\x74\xD6\x54\x4B\xE2\x97\x5B\x25\x4E\x09\xFB\x65\x4B\xCD\x77\x5F\x4E\x81\x2C\x35\x2A\x3F\x5C\x38\xE9\x48\x1C\x68\x2B\x74\x8A\x5F\x6E\x95\x7E\x39\xAA\xF9\xE5\x16\xEF\x23\x6D\xA9\x55\xFA\xE5\x56\xAA\x2C\x25\x14\x5F\x4E\x15\x45\xCC\x4B\x44\x6C\xDD\x59\x52\xFA\xE5\x26\xFB\x65\x6A\xB1\x4B\xE5\xE0\x49\x6A\x7D\xC1\xFE\x9B\xC1\x74\x44\xD0\xF9\x3D\xB1\x62\x55\xEC\x5B\xFF\x9E\x6B\x16\xD6\x90\xE2\x47\x44\x86\xA2\xF5\x85\x3C\x96\x38\xE4\x0C\x0B\x0B\x59\xA2\x97\xA8\xC1\xCC\x25\x4E\x0F\xF3\xE6\x40\x7C\x93\x33\x83\xBC\xC5\x8D\xF2\x1E\xF8\xB3\xA9\x72\x90\xB5\x1D\x64\x69\x65\x38\x01\x7C\xCB\x34\x1B\xE5\x8C\x6C\x4E\x2F\x91\xE5\xD7\xB9\xCA\x93\x59\x66\xC2\xA6\x60\x99\x82\x2D\xF5\x66\x3D\x80\x96\xA7\xA5\x55\xAB\xF8\xA4\x56\x8D\x22\x2B\x63\x82\x26\x96\x34\xDB\xCA\x06\x12\x6D\x8E\x89\xED\x8A\x65\x4A\x1C\x0E\xF2\x84\xE2\x75\xD9\x16\x86\xC4\x53\x97\xE2\x5B\xF6\x64\xCC\x78\x3E\xE7\xDD\xBA\x72\xC9\x20\x6F\x9E\x51\x92\xBF\xCC\xB1\xBE\xBE\xC3\xA4\xD4\x12\x71\xA3\x53\xEB\x05\x78\x89\x4B\xB2\x39\x87\x59\x53\x2F\x51\x22\x6C\x0D\xCA\xD1\x34\xC7\xFA\x9B\xA3\x26\xAF\xDD\x14\x9A\x67\x14\x78\x0E\x78\xB1\x6C\xCE\xD2\x9C\x1F\x6A\x49\x95\x2B\x68\xB6\xF7\xC0\x87\xFE\x04\x7C\xE8\x4F\xC9\x87\xAE\xF3\xA1\x3D\xD2\x63\xAC\xE8\x30\xCD\xB2\x89\x39\x64\xB4\x2E\x2D\xD8\xFF\x8E\xD0\x72\x9C\xC5\xC2\x51\xCB\xB6\x9C\x72\x3E\x62\x6B\x5A\x22\x55\xA7\xF3\x2B\x82\xBF\x71\xD1\xB3\x00\x64\x48\x2D\xAA\x36\x99\x65\x78\x5A\x99\x60\x39\x92\x0D\x19\xD7\x1E\xF0\xF4\xE1\xA2\x12\x54\x87\x7E\x5E\x86\x6A\x89\x0C\x03\x10\x79\x00\xC4\x1F\x1A\x96\x36\x76\x90\x71\x78\x43\x52\x03\x8A\x59\x5C\x35\x38\xAB\xE0\x69\x99\x9F\x08\x1B\x2C\xAB\xA6\xA8\x14\x94\xE7\xE5\xAA\xC2\x44\x11\xF2\x72\x91\x78\x75\x4E\xC2\x4A\x2B\x6E\x88\x29\xBA\xA9\x66\xB1\x45\xE6\x35\x4B\x84\xAD\x8C\xB7\x92\x1E\x64\x71\xD8\x3B\xEC\x29\x48\x09\xFA\x39\xA7\xB4\x94\x30\x17\x43\xD7\x22\xBD\x90\x2B\x2F\x9B\x2E\x64\x63\x15\xD6\xC4\x0A\xF2\xC0\x27\x97\x27\xAE\x44\x89\x09\x2A\x51\x2C\x45\xA2\x8A\x45\x05\xA5\x02\x34\xA9\x77\x9F\xD6\xCC\x8E\x7E\x0E\x41\xA6\xE6\x28\xDC\x0C\x72\x45\x5A\x58\xA3\xE6\xA2\x32\x81\x06\x8B\x93\xE4\x0D\x5E\x47\xF6\x82\x98\x99\x00\x0F\x2E\xC9\x5A\x0E\xC5\x5F\xA0\x77\x16\xCA\xEB\x27\xB3\xD2\x20\xE9\xBA\x4F\x69\x98\x98\xC9\x9B\x21\xB2\xFA\x00\x9A\x47\xA4\x06\x59\xEC\xBD\x93\xC3\x8B\x29\x50\x2B\x53\x94\x64\xA8\x97\x28\x66\xD6\x07\xEE\x8D\x42\x74\xF0\x40\x38\x09\xDF\x54\x10\x6A\x14\x84\x64\x9D\x2C\x26\xE5\xDE\x18\x48\xA0\x1C\x0D\x32\x94\x13\x43\xA6\xA9\xE1\xE0\x9B\x1C\x6F\xFD\x7A\x1C\x92\x92\x0C\x2D\xC5\x64\x05\x2A\x42\x9E\xEC\x65\x0E\xAE\xC1\xF8\x6D\xF1\xED\x14\xA9\xC5\x98\xB7\x7C\xC4\x47\xF1\xB6\xC6\x7E\x17\xD1\x8C\x45\xF8\x5A\xEE\x83\xF5\x8D\xC9\x6E\x5A\x0C\xCD\xC3\xC6\xE6\x93\x69\x97\x64\xE8\x90\x33\x7C\xDE\x20\x40\x58\xDB\x9D\x12\x71\x90\x0C\xB3\x21\x4E\x3A\x68\x38\x18\x1E\xB3\x8D\xC5\xD6\x0C\x73\xEC\xFF\x14\xDC\x70\x32\x34\x1A\xE4\x18\x8E\x48\x1E\xD8\xB9\x18\x00\x00\x55\x35\x61\xDE\xFE\x5F\x61\xBD\x9E\xB6\x14\xB9\x7E\x92\x9B\x90\xF6\x06\xBA\x26\xC7\x22\x6B\x32\xC1\xAD\x8F\x11\xB3\xEB\x65\xAE\x30\x49\x09\xC7\x29\x61\xAE\x32\xF0\x91\x0F\x4B\x4A\xAA\x74\xB7\xB6\x4C\xC1\xF8\x79\x56\xFB\x94\xEC\x9C\x4E\xCA\x14\xED\x14\x9F\x2E\x30\x6C\x24\x70\xC8\x9E\x0C\xEC\x03\xDC\x9A\x84\x56\xE4\xFD\x67\x08\x9D\xE2\x4E\xB4\x0F\x72\x67\xA7\xEA\x94\xBD\x87\x7E\xEF\xA1\x9F\x5A\xEB\x1D\xEB\x9C\x9C\xFA\x8C\x74\x7E\x47\xF9\xDE\x47\xB8\xB7\x1D\x7A\xC5\x81\x19\xF6\x97\xBC\xAA\x62\x1E\x12\x49\x44\x55\x35\x06\x7D\x27\x74\xFE\xC2\xE7\x05\x84\x7E\x18\xB2\x2B\x36\x84\xF6\xD7\xD9\x8E\x48\x44\x6D\xE7\xE8\xBD\x15\x2E\xE4\xC8\x8E\x1A\x2B\x6F\xA5\x2A\x8B\x71\xB2\x95\xBD\x65\x80\x58\x85\x22\x1C\x14\xA6\x11\x76\xEE\xB8\x5D\x40\x3D\xE0\xF0\xD4\x1C\x6B\x26\xC4\xAC\x80\x17\xAD\x53\xC2\x2C\x01\x03\x1C\x30\x1F\x20\x01\x83\xC0\xBE\x83\x18\xD5\xD0\xF1\x83\x44\xA2\x36\x61\x88\x2A\xE1\xC6\x81\x23\x0A\x84\x88\x02\x55\x44\x51\xE2\x76\x92\x01\x67\x44\xC1\xF5\xFA\xD4\x31\x33\x0E\xB2\x48\x84\x81\x01\x71\x56\x4F\x50\xBA\x21\x16\x06\x28\x62\x61\x22\x11\xD4\x4B\xC2\xF3\x72\xA8\x24\x01\x2F\x09\xA1\xB7\x99\xA4\x14\x26\xF6\x36\xD3\x94\xC4\x74\x51\x19\xDB\x91\x6F\xAC\x78\x70\xF0\x2C\xA0\xFD\x29\x4B\x56\x58\xB0\xF2\xDA\xD0\x7E\x0B\xB6\x07\x1F\x11\x45\x4C\xB1\x69\xEB\x11\x12\xEA\x11\xD2\x7C\xF2\x88\x02\x53\x11\xD2\xD4\xC3\x0A\xAF\xF3\x71\x91\xA5\xC8\x7F\x8B\xD0\xE2\x2D\x54\x22\x8C\xFD\x6D\x85\xB6\x90\xB1\xE6\x5F\x24\xF4\x05\xFF\xA2\xBC\x63\x37\x1C\x56\xE2\x41\x2E\x41\x35\x21\x6E\x18\x0D\xF2\x66\x11\x56\x1A\xBC\xE9\x5B\x84\x27\xE4\xBE\x47\x6E\x75\x24\x3E\x53\x5C\x44\x96\xC8\x47\x16\xCD\x11\x3A\xB3\x12\x59\x1A\x14\x95\xF2\xFB\x24\xDC\x1D\x0A\xAB\x35\x42\xED\x82\x50\x33\x44\x96\x88\x23\x4B\x44\x96\x43\x8A\xA5\x26\x3F\x9A\xD4\x0E\x91\x85\x29\x32\x92\x12\x5C\x4C\xC6\x21\x99\x12\x06\xAC\x41\x56\x82\x4B\x6B\x51\x92\x68\xB9\x5A\x99\xB1\x13\xEC\x49\xBF\x4F\x04\x06\xC2\x85\x33\xC5\x2E\xA8\x36\x38\x78\x75\xFB\x9D\x1D\xC0\xB4\x3F\x40\xD4\x9C\x87\xE9\xEA\xA6\xC4\x78\x9F\x6E\x82\x4F\x2F\x92\x13\x31\x00\x3D\x76\x93\xE0\xF5\x9D\x6B\x3F\x82\x73\xB5\xE0\x14\x4D\xA6\x6D\xB9\x72\x14\x72\x23\xBF\x72\x24\xCE\x82\x93\x51\x26\xAE\x29\x5A\xF4\x67\x50\x66\x3B\x5A\x94\xF3\xAF\x96\x21\xF6\x61\xC4\x11\x81\xC4\x61\x2D\xF1\x7D\x90\xF3\x69\x9D\xD1\x42\x82\x2D\xFB\xAD\xEA\x98\xAB\x82\x9B\x1E\xBF\x11\x54\x7C\x50\xBC\x94\x6A\x99\x2B\x7E\x46\x8E\xCF\x8A\xF5\xAF\x8A\xDB\x0F\x37\x9A\xB7\x0E\xED\x1F\x21\x36\xC2\x6A\x45\xFA\x99\xAB\x62\x35\x49\x02\x58\x7A\x31\x72\xDF\x5A\x5C\x29\x12\x6E\x71\xB0\x22\xD8\x0A\x87\xA1\x3C\x5E\xE0\xEC\xAE\x48\x64\x79\xAB\x04\xB6\xC2\xB7\x44\x38\x73\xA7\x87\xEE\xF4\x6D\x4A\xFC\xF3\x9B\xA9\x0E\x6B\x52\x43\xF4\xE9\x46\x92\xC0\x98\xF5\x85\x92\xC5\x39\xB6\xF1\x17\x07\x7C\x46\x76\xAD\x75\x7B\x36\xDC\x11\xB8\xD7\x38\x60\xDF\x7B\x29\x05\x87\x84\x43\xF7\x1B\x77\xEE\xA8\x57\x79\x7D\x14\x58\x9B\xAB\x96\x3D\xB2\xFB\x57\x7C\xD5\x7D\x30\xF2\xB3\xE3\xF5\x3A\xA5\x7D\xEB\x6F\x1F\x3A\x92\xA2\x6C\xD9\xCF\x84\x7B\x15\x6E\xDA\x92\xB6\x41\x68\x0B\x23\xA4\xFB\xDB\xF6\xA2\x30\x10\xAC\x46\xBA\x73\x13\xC6\x93\xE2\x1D\xC3\xB9\xBE\xF2\x67\x6C\xCE\x76\xFD\xBD\x90\xEB\x0C\xF2\x32\x19\x63\xBB\xD0\xF6\x32\xEA\xB0\x95\x3B\x39\xD6\x97\x90\x5D\xDD\x19\x14\x5E\x48\x72\xF4\xF3\x00\x9D\xBF\x2E\x8E\x6A\x4A\xF6\x98\x58\x06\x93\x2A\x26\x97\x5E\xD5\xFE\x2A\x72\x00\x43\x49\xFE\x2B\x36\x55\x60\xD3\x99\x8B\x72\xF4\x47\x52\x4C\xF6\x6F\x3C\x59\xBF\xA8\xF8\xAE\xF3\x80\x55\xAB\x6F\x50\x13\xC3\x40\x5A\x75\xAD\x55\x68\x3B\x23\x9E\xCD\xE7\x19\xF6\xBF\x8C\x58\x57\x10\x71\x51\x25\x3E\xB3\xF2\xB7\x7D\x17\xD6\x02\xAD\x60\xE3\x7E\x9E\xA2\x71\x28\xFC\x55\x55\xA6\xAC\x37\x78\xD1\xDD\x13\xD3\x33\x03\x52\x6D\x2C\xC6\x89\x79\x15\x88\x15\xDD\x95\x84\x13\x80\x07\xA4\xCD\x04\xD2\xEA\x38\xA4\x8D\x47\xBA\xAD\x6D\xA5\x5E\x9F\xAA\xB1\x7C\x21\xB7\xF6\x0A\xC9\x59\x9F\x95\xD4\x8F\xAF\x95\x40\x57\xDC\x17\x29\x27\x45\x5B\xB9\xA6\x60\x00\xC6\x1F\x8A\x3E\x01\x3F\xB9\x4C\x93\x03\x89\x09\x07\x52\x32\xEB\xFE\x4E\x24\x70\x96\x57\x4C\x15\x47\x31\x16\xDB\x16\xE8\x92\x72\xB4\x2F\xE0\x7E\x08\xE3\xE8\xEA\x42\x2F\x9A\xB9\x8B\x99\x3B\xF4\x2E\x80\x05\x6A\xB8\x0B\xAB\x29\x50\xC3\x9D\x5B\x93\x8B\x4F\x3F\x4D\xF9\x69\xB5\x29\x41\x7F\x31\x55\xD6\x1D\x12\x20\x76\x16\x7A\x4C\x46\x94\x7C\xBA\x58\x9B\x74\xC0\xBC\x4A\x8C\x75\x86\x6D\xAC\x83\xEE\x53\x82\xB6\x8B\xFC\x7D\xD5\x5F\x69\x8C\xE5\x90\x5D\xEC\x2E\xF6\x68\x2E\x17\xB9\x82\xBB\x61\x97\x2C\x5A\x10\xA7\x2B\x99\x9F\x60\xE2\x0D\x22\x8F\x44\x67\xEC\x10\xCF\x03\xE4\xB1\xCB\x57\x59\x68\x8A\xDD\x4F\x80\xC5\x8D\x1D\x5D\x4C\x35\xC5\xEE\x67\xB0\x9A\x6A\xD2\x25\x51\x89\xF7\x5B\x14\x79\xF0\x03\x1E\xD2\x19\x73\x67\x2C\x9D\x6C\xD4\xF1\x79\x00\xF7\xCA\x20\x8F\xDD\x3F\xC3\x25\x0F\x28\xD3\x9F\x7B\x19\x4C\xED\x6F\xEC\xE5\xE3\xFE\xA0\xFC\x84\x5A\x0B\x18\x40\x60\xF5\xAA\x41\xB8\x77\xF5\x2C\xA9\xC0\x6F\x44\x66\x40\x6A\x8B\x5D\x82\x1A\x73\x07\x6A\xA6\x3B\x50\x93\xEE\x60\x6C\x98\x1E\x1F\x26\xEA\x2D\x56\x94\xAC\x0E\xFC\xED\x45\x09\x0B\xDB\x56\xEC\x7D\xC5\x7B\xEC\x2B\x2A\x97\xD5\xC9\x83\x4A\x74\x50\x49\x65\x38\x51\xD8\x1C\xD3\xBF\x74\xF1\xBF\x96\xFD\x7F\x5E\xEE\x7F\x5F\x19\xE4\x0D\xF7\x2F\x70\x89\x2D\x74\xEE\x97\x34\x14\x7F\x06\xEA\x7F\x11\x7C\xCC\x5F\x0C\x8D\xE2\x6B\x12\x9E\x4D\xF9\x6C\xF9\x17\xCB\x8E\x80\xD0\x5B\x70\x48\x8F\x65\x5B\x28\x8E\x06\x9D\x1F\x05\x4C\x58\x38\x8A\x24\x77\xA8\x99\x4B\x21\x64\xB1\x7D\xB1\x9D\xB2\xE1\x74\xFE\xD6\x9F\xF3\xBC\x7B\xE9\xFC\x5D\x71\xEA\xAB\x23\x67\x27\x1B\xDA\x93\x0D\xCD\xC9\x86\x16\x53\xE4\x03\x3E\xA9\x2D\x32\x03\x17\x5D\x4C\x8D\xFB\xFE\x5B\x92\xA9\xBA\xC8\x07\xAD\xD4\x78\x9D\x86\x7D\x18\xC9\x44\x33\x31\xD1\x5C\x4C\xB5\xFB\xAD\x30\xD1\x84\x89\x7A\x6C\xA2\x0F\x05\x6A\x7A\xA2\x72\xDF\x9B\x98\xA8\x66\x4C\xD4\x93\xBC\x37\x26\x1B\x38\x81\x42\xFB\x10\x94\x69\x5D\xC8\xF5\xF8\xD1\x21\xC5\x87\x99\xC4\x76\x15\x8E\xD4\xD1\xF2\x68\x19\xFD\x39\xFF\xC2\x6A\xAE\x16\x32\xBD\xEC\xF3\x7E\x45\xF8\xFF\xBD\x5B\x90\x5F\x18\x48\x6D\x65\x6A\xD9\x9F\xC8\xCC\x72\xEB\x88\xE0\x09\x80\xC3\xE5\x17\x0F\x33\x33\x9D\x46\x91\x21\x7D\x64\x7F\xAA\x23\x1C\xA9\x43\xF9\x39\x60\xF4\x82\x37\x88\xFF\xFC\xA0\xF8\xF2\xFC\xD8\xA2\x2F\x14\x66\x54\x5B\xBB\xD6\x16\xD2\xA6\x3C\x1A\x0B\xF6\x26\x8C\x78\x74\xE9\x2E\x71\x8F\x7B\x71\xF0\xDE\xDB\x99\x29\xF2\x26\x4E\xD2\xBD\xC7\xBF\xCB\x5B\x82\xA9\xAE\xFA\xCB\x09\x9F\x77\x49\xC4\xA9\x16\x69\xA8\xA5\x72\x26\xAF\xFE\xFB\x3F\xE0\xBF\xF7\x9F\xCF\x4C\x6D\xCC\x6C\x46\x1A\x9C\xE7\x05\x06\xEE\xBE\x9D\x35\x6A\x9C\xFD\x70\x8A\x9F\x98\x34\x35\xEE\xBE\x9D\xC5\x9E\x21\xB4\x0E\xB3\xA4\xB8\xE9\xF6\x63\x9B\x92\x16\x46\xEE\x9C\xE7\x37\xF2\x19\x81\x78\xAA\xA6\x1B\x65\x09\x4F\x89\xA8\xC9\x14\xE5\x2E\x11\xE5\xA7\x12\x35\xC8\x9B\xCC\xBA\x78\xFD\x26\x7B\x03\xA4\xE6\x96\xBF\x50\x95\x0C\xB6\xB5\x2D\x5C\x0E\xDC\x8B\x9C\x41\xF1\x81\x93\xC7\xC8\xFD\x4E\x0A\x05\x15\xE6\x92\xBF\x6A\x5E\xB7\xB5\x2D\x6D\xAC\x57\x7F\x2C\xB1\x92\x84\x26\xDB\xEF\xDD\xCD\x62\x4B\xB1\xFD\x11\x2A\x35\x52\x47\xB5\x0B\xB7\xC9\x2C\xD7\x3D\xBE\x2A\xD9\xED\x8F\xC1\x3F\x3F\x94\xE7\x18\x24\x63\x26\xA8\x17\x32\xB3\x0C\x59\xE4\x53\x69\x6F\x82\x5A\x2E\xE0\x48\x6F\x89\x75\x0A\x6B\x6C\x82\xAA\x30\xC1\xA8\xBC\x1D\x96\x0B\x42\xE1\x33\x22\x73\xD4\xB9\x5B\x38\x07\xC2\xCE\xDF\xF3\xF7\xCE\x0F\xE5\x5A\xE6\x26\x1A\x09\x83\x9D\x77\x0A\xC7\xC4\xF9\x44\x71\xE6\xE9\x7C\x10\xEE\x95\xED\xAA\x1C\x77\x5A\x6B\x12\xB4\xFC\x66\x4D\x25\x93\x01\x32\x9D\x1F\xFB\x7B\x02\xC9\x04\x09\x3B\x7F\x26\xE5\x01\x28\x11\x58\xAE\x77\x39\xE0\x7E\x4F\x2B\x3D\x52\x47\xC5\xEF\xEE\x84\xEE\x88\x93\xF3\x46\x79\x9B\x56\xFD\xB4\x3A\x97\x00\x2A\x6D\xA2\x46\x0C\xB6\xF3\x87\xC1\xC7\x61\xE7\xED\xC2\xDB\x15\xDF\x7C\x14\x68\x87\x9F\x98\xB6\x72\x53\xC0\xCE\x07\x1E\x4D\x30\xF0\xBF\xF0\x3D\xBE\x9A\xC6\x84\x02\x3B\x3F\x3F\x94\xA7\xB8\x57\x20\x53\xC1\xAE\x03\xEC\xB8\x90\x45\xCB\x20\xFB\xC4\x10\x7E\x4B\x4E\x62\xB2\xAB\x0D\xE1\x56\x86\xDC\xC5\x07\xDD\xB1\x9D\x1F\x97\xBF\x3F\x16\x36\x24\xE6\x51\x83\x5D\xEE\xC5\x3C\xBB\xB8\xD5\xF9\xE3\xA2\xB9\xF3\x8F\x1E\xF6\x36\xDA\xBA\x16\x44\x07\x66\x4C\x07\xDA\xEB\x40\x8F\xE9\xC0\x14\x3A\xD0\x1F\xA3\x83\x79\x4B\x4A\x8E\x8F\x66\x4C\xFB\xBF\x89\x85\xFA\xFF\x64\x4C\xFD\xC7\x2C\x9D\x7C\xD4\xD2\x72\x68\x0D\x53\x5C\xDB\x27\x52\xE1\x75\x9C\x39\x4D\xD8\xF9\xF3\x69\xF6\xEC\xCF\x23\x8E\x1E\xF1\xA5\x25\xB4\x95\xAB\x47\xEF\x54\x3F\x1F\xB4\xCB\x6B\x37\x7E\x9C\x16\xBF\xAD\x3B\x72\xC1\x22\x1F\xF5\x65\xC4\xFF\xD2\x20\x4C\x07\x6B\x1F\x43\xA9\xA7\x7C\x68\x73\x7B\xBB\x7F\xA3\xB7\x4D\x52\xC7\x05\x52\xA7\x36\xDC\xBF\xDD\x87\xEB\xBD\xED\x83\x3E\xC0\xBF\xB7\xCC\x6E\x6F\xA7\x8F\x3F\x69\x5D\x84\xAA\xDE\x13\xA7\x8B\x2F\x55\xAD\xA2\x52\x97\x05\x95\x66\xA2\x9E\x32\x9A\x59\x4E\x19\x4F\x57\x53\x36\x26\x8A\x29\x93\x8F\xA8\xA5\x6C\xCE\x2A\xA5\x6C\x8D\x57\x52\xDA\xD9\x85\x94\xED\x99\x75\x94\xE9\x44\x19\xE5\xDC\x71\x55\x94\xF3\xC7\x14\x51\x76\x8E\xAB\xA1\x3C\x31\x55\x42\x79\xF2\xB8\x0A\xCA\x59\x55\x92\xBE\x22\xEB\x9E\x63\xEB\x27\x4F\x1D\x57\x30\x79\xEF\xB1\xF5\x92\xF7\x4D\x96\x4B\x9E\x9E\xA8\x96\xFC\xEC\x44\xB1\xE4\xFD\x93\xB5\x92\x0B\xD3\xA5\x92\x0F\x8C\x57\x4A\x3E\x38\x59\x28\xF9\xD0\x54\x9D\xE4\xC3\x65\x99\x24\xD5\xAB\x24\xB3\xC9\x22\xC9\x7C\xA2\x46\xF2\x91\xA9\x12\xC9\x47\x6B\x15\x92\x8F\xCD\x2E\x90\xFC\xDC\x54\x49\xE4\xE7\xAB\x8A\xC8\x33\x33\x0A\x22\xCF\xD6\xEA\x21\xBF\x30\xBB\x1C\xF2\xDC\xB1\xD5\x90\xE7\xA7\x8A\x21\x2F\x4C\xD4\x42\x3E\x3E\x59\x0A\xF9\xC5\xE3\x2A\x21\x9F\x98\x2E\x84\xFC\x52\xAD\xD8\xF3\xCB\xF5\xF2\xD9\x27\x6B\x05\x92\x5F\xA9\xD7\x47\x3E\x55\x2F\x8F\x5C\xAC\xAA\x23\x9F\x9E\x55\x1C\xF9\xD5\x63\x6A\x23\x9F\x99\x2A\x8D\x7C\xF6\x98\xCA\xC8\xE7\x8E\x2D\x8C\xFC\xDA\xF1\x75\x91\xB3\x6A\x1F\x3D\xAC\x5F\x3F\xB6\x2A\xF2\xF9\xE9\xA2\xC8\xA5\xE9\x9A\x48\x37\xA3\x24\x72\x79\x66\x45\xE4\x37\x66\x17\x44\xBE\x30\xB3\x1E\x72\x65\xB2\x75\xB8\xB7\xD5\xDF\x5D\x9D\x5D\x24\xB9\x36\x51\x23\xF9\xBF\x01\x00\x00\xFF\xFF\xD3\xFA\xF3\x7F\xCB\x2F\x00\x00") diff --git a/internal/compiler/wasm/opa/opa.wasm b/internal/compiler/wasm/opa/opa.wasm index 463cea91da..0036b6e7fe 100755 Binary files a/internal/compiler/wasm/opa/opa.wasm and b/internal/compiler/wasm/opa/opa.wasm differ diff --git a/internal/compiler/wasm/wasm.go b/internal/compiler/wasm/wasm.go index 9558954e86..c5e4b23f5b 100644 --- a/internal/compiler/wasm/wasm.go +++ b/internal/compiler/wasm/wasm.go @@ -20,17 +20,29 @@ import ( ) const ( - opaFuncPrefix = "opa_" - opaJSONParse = "opa_json_parse" - opaNull = "opa_null" - opaBoolean = "opa_boolean" - opaStringTerminated = "opa_string_terminated" - opaNumberInt = "opa_number_int" - opaValueBooleanSet = "opa_value_boolean_set" - opaValueNotEqual = "opa_value_not_equal" - opaValueCompare = "opa_value_compare" - opaValueGet = "opa_value_get" - opaValueIter = "opa_value_iter" + opaTypeNull int32 = iota + 1 + opaTypeBoolean + opaTypeNumber + opaTypeString + opaTypeArray + opaTypeObject +) + +const ( + opaFuncPrefix = "opa_" + opaJSONParse = "opa_json_parse" + opaNull = "opa_null" + opaBoolean = "opa_boolean" + opaStringTerminated = "opa_string_terminated" + opaNumberInt = "opa_number_int" + opaNumberSize = "opa_number_size" + opaValueBooleanSet = "opa_value_boolean_set" + opaValueNumberSetInt = "opa_value_number_set_int" + opaValueCompare = "opa_value_compare" + opaValueGet = "opa_value_get" + opaValueIter = "opa_value_iter" + opaValueLength = "opa_value_length" + opaValueType = "opa_value_type" ) // Compiler implements an IR->WASM compiler backend. @@ -165,6 +177,9 @@ func (c *Compiler) compileBlock(block ir.Block) ([]instruction.Instruction, erro case ir.ReturnStmt: instrs = append(instrs, instruction.I32Const{Value: int32(stmt.Code)}) instrs = append(instrs, instruction.Return{}) + case ir.AssignVarStmt: + instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) + instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) case ir.AssignBooleanStmt: instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Target)}) if stmt.Value { @@ -173,6 +188,10 @@ func (c *Compiler) compileBlock(block ir.Block) ([]instruction.Instruction, erro instrs = append(instrs, instruction.I32Const{Value: 0}) } instrs = append(instrs, instruction.Call{Index: c.function(opaValueBooleanSet)}) + case ir.AssignIntStmt: + instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Target)}) + instrs = append(instrs, instruction.I64Const{Value: stmt.Value}) + instrs = append(instrs, instruction.Call{Index: c.function(opaValueNumberSetInt)}) case ir.ScanStmt: if err := c.compileScan(stmt, &instrs); err != nil { return nil, err @@ -189,10 +208,15 @@ func (c *Compiler) compileBlock(block ir.Block) ([]instruction.Instruction, erro instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Target)}) instrs = append(instrs, instruction.I32Eqz{}) instrs = append(instrs, instruction.BrIf{Index: 0}) + case ir.LenStmt: + instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) + instrs = append(instrs, instruction.Call{Index: c.function(opaValueLength)}) + instrs = append(instrs, instruction.Call{Index: c.function(opaNumberSize)}) + instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) case ir.EqualStmt: instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.A)}) instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.B)}) - instrs = append(instrs, instruction.Call{Index: c.function(opaValueNotEqual)}) + instrs = append(instrs, instruction.Call{Index: c.function(opaValueCompare)}) instrs = append(instrs, instruction.BrIf{Index: 0}) case ir.LessThanStmt: instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.A)}) @@ -249,6 +273,18 @@ func (c *Compiler) compileBlock(block ir.Block) ([]instruction.Instruction, erro instrs = append(instrs, instruction.I32Const{Value: c.stringAddr(stmt.Index)}) instrs = append(instrs, instruction.Call{Index: c.function(opaStringTerminated)}) instrs = append(instrs, instruction.SetLocal{Index: c.local(stmt.Target)}) + case ir.IsArrayStmt: + instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) + instrs = append(instrs, instruction.Call{Index: c.function(opaValueType)}) + instrs = append(instrs, instruction.I32Const{Value: opaTypeArray}) + instrs = append(instrs, instruction.I32Ne{}) + instrs = append(instrs, instruction.BrIf{Index: 0}) + case ir.IsObjectStmt: + instrs = append(instrs, instruction.GetLocal{Index: c.local(stmt.Source)}) + instrs = append(instrs, instruction.Call{Index: c.function(opaValueType)}) + instrs = append(instrs, instruction.I32Const{Value: opaTypeObject}) + instrs = append(instrs, instruction.I32Ne{}) + instrs = append(instrs, instruction.BrIf{Index: 0}) default: var buf bytes.Buffer ir.Pretty(&buf, stmt) diff --git a/internal/ir/ir.go b/internal/ir/ir.go index 48736a6783..6e8c4128a0 100644 --- a/internal/ir/ir.go +++ b/internal/ir/ir.go @@ -137,6 +137,13 @@ type DotStmt struct { Target Local } +// LenStmt represents a length() operation on a local variable. The +// result is stored in the target local variable. +type LenStmt struct { + Source Local + Target Local +} + // ScanStmt represents a linear scan over a composite value. The // source may be a scalar in which case the block will never execute. type ScanStmt struct { @@ -159,6 +166,19 @@ type AssignBooleanStmt struct { Target Local } +// AssignIntStmt represents an assignment of an integer value to a +// local variable. +type AssignIntStmt struct { + Value int64 + Target Local +} + +// AssignVarStmt represents an assignment of one local variable to another. +type AssignVarStmt struct { + Source Local + Target Local +} + // MakeStringStmt constructs a local variable that refers to a string constant. type MakeStringStmt struct { Index int @@ -217,3 +237,13 @@ type NotEqualStmt struct { A Local B Local } + +// IsArrayStmt represents a dynamic type check on a local variable. +type IsArrayStmt struct { + Source Local +} + +// IsObjectStmt represents a dynamic type check on a local variable. +type IsObjectStmt struct { + Source Local +} diff --git a/internal/planner/planner.go b/internal/planner/planner.go index 81778796cf..60350e3037 100644 --- a/internal/planner/planner.go +++ b/internal/planner/planner.go @@ -46,17 +46,22 @@ func (p *Planner) WithQueries(queries []ast.Body) *Planner { func (p *Planner) Plan() (*ir.Policy, error) { for _, q := range p.queries { + p.curr = &ir.Block{} + defined := false - p.blocks = append(p.blocks, ir.Block{}) - p.curr = &p.blocks[len(p.blocks)-1] - - if err := p.planQuery(q, 0); err != nil { + if err := p.planQuery(q, 0, func() error { + p.appendStmt(ir.ReturnStmt{ + Code: ir.Defined, + }) + defined = true + return nil + }); err != nil { return nil, err } - p.appendStmt(ir.ReturnStmt{ - Code: ir.Defined, - }) + if defined { + p.blocks = append(p.blocks, *p.curr) + } } p.blocks = append(p.blocks, ir.Block{ @@ -79,14 +84,14 @@ func (p *Planner) Plan() (*ir.Policy, error) { return &policy, nil } -func (p *Planner) planQuery(q ast.Body, index int) error { +func (p *Planner) planQuery(q ast.Body, index int, iter planiter) error { if index >= len(q) { - return nil + return iter() } return p.planExpr(q[index], func() error { - return p.planQuery(q, index+1) + return p.planQuery(q, index+1, iter) }) } @@ -149,7 +154,7 @@ func (p *Planner) planNot(e *ast.Expr, iter planiter) error { B: truth, }) - return nil + return iter() } func (p *Planner) planExprTerm(e *ast.Expr, iter planiter) error { @@ -171,13 +176,7 @@ func (p *Planner) planExprCall(e *ast.Expr, iter planiter) error { switch e.Operator().String() { case ast.Equality.Name: - return p.planBinaryExpr(e, func(a, b ir.Local) error { - p.appendStmt(ir.EqualStmt{ - A: a, - B: b, - }) - return iter() - }) + return p.planUnify(e.Operand(0), e.Operand(1), iter) case ast.Equal.Name: return p.planBinaryExpr(e, func(a, b ir.Local) error { p.appendStmt(ir.EqualStmt{ @@ -231,6 +230,231 @@ func (p *Planner) planExprCall(e *ast.Expr, iter planiter) error { } } +func (p *Planner) planUnify(a, b *ast.Term, iter planiter) error { + + switch va := a.Value.(type) { + case ast.Null, ast.Boolean, ast.Number, ast.String, ast.Ref: + return p.planTerm(a, func() error { + return p.planUnifyLocal(p.ltarget, b, iter) + }) + case ast.Var: + return p.planUnifyVar(va, b, iter) + case ast.Array: + switch vb := b.Value.(type) { + case ast.Var: + return p.planUnifyVar(vb, a, iter) + case ast.Ref: + return p.planTerm(b, func() error { + return p.planUnifyLocalArray(p.ltarget, va, iter) + }) + case ast.Array: + if len(va) == len(vb) { + return p.planUnifyArraysRec(va, vb, 0, iter) + } + return nil + } + case ast.Object: + switch vb := b.Value.(type) { + case ast.Var: + return p.planUnifyVar(vb, a, iter) + case ast.Ref: + return p.planTerm(b, func() error { + return p.planUnifyLocalObject(p.ltarget, va, iter) + }) + case ast.Object: + if va.Len() == vb.Len() { + return p.planUnifyObjectsRec(va, vb, va.Keys(), 0, iter) + } + return nil + } + } + + return fmt.Errorf("not implemented: unify(%v, %v)", a, b) +} + +func (p *Planner) planUnifyVar(a ast.Var, b *ast.Term, iter planiter) error { + + if la, ok := p.vars[a]; ok { + return p.planUnifyLocal(la, b, iter) + } + + return p.planTerm(b, func() error { + target := p.newLocal() + p.vars[a] = target + p.appendStmt(ir.AssignVarStmt{ + Source: p.ltarget, + Target: target, + }) + return iter() + }) +} + +func (p *Planner) planUnifyLocal(a ir.Local, b *ast.Term, iter planiter) error { + switch vb := b.Value.(type) { + case ast.Null, ast.Boolean, ast.Number, ast.String, ast.Ref: + return p.planTerm(b, func() error { + p.appendStmt(ir.EqualStmt{ + A: a, + B: p.ltarget, + }) + return iter() + }) + case ast.Var: + if lv, ok := p.vars[vb]; ok { + p.appendStmt(ir.EqualStmt{ + A: a, + B: lv, + }) + return iter() + } + lv := p.newLocal() + p.vars[vb] = lv + p.appendStmt(ir.AssignVarStmt{ + Source: a, + Target: lv, + }) + return iter() + case ast.Array: + return p.planUnifyLocalArray(a, vb, iter) + case ast.Object: + return p.planUnifyLocalObject(a, vb, iter) + } + + return fmt.Errorf("not implemented: unifyLocal(%v, %v)", a, b) +} + +func (p *Planner) planUnifyLocalArray(a ir.Local, b ast.Array, iter planiter) error { + p.appendStmt(ir.IsArrayStmt{ + Source: a, + }) + + blen := p.newLocal() + alen := p.newLocal() + + p.appendStmt(ir.LenStmt{ + Source: a, + Target: alen, + }) + + p.appendStmt(ir.MakeNumberIntStmt{ + Value: int64(len(b)), + Target: blen, + }) + + p.appendStmt(ir.EqualStmt{ + A: alen, + B: blen, + }) + + lkey := p.newLocal() + + p.appendStmt(ir.MakeNumberIntStmt{ + Target: lkey, + }) + + lval := p.newLocal() + + return p.planUnifyLocalArrayRec(a, 0, b, lkey, lval, iter) +} + +func (p *Planner) planUnifyLocalArrayRec(a ir.Local, index int, b ast.Array, lkey, lval ir.Local, iter planiter) error { + if len(b) == index { + return iter() + } + + p.appendStmt(ir.AssignIntStmt{ + Value: int64(index), + Target: lkey, + }) + + p.appendStmt(ir.DotStmt{ + Source: a, + Key: lkey, + Target: lval, + }) + + return p.planUnifyLocal(lval, b[index], func() error { + return p.planUnifyLocalArrayRec(a, index+1, b, lkey, lval, iter) + }) +} + +func (p *Planner) planUnifyLocalObject(a ir.Local, b ast.Object, iter planiter) error { + p.appendStmt(ir.IsObjectStmt{ + Source: a, + }) + + blen := p.newLocal() + alen := p.newLocal() + + p.appendStmt(ir.LenStmt{ + Source: a, + Target: alen, + }) + + p.appendStmt(ir.MakeNumberIntStmt{ + Value: int64(b.Len()), + Target: blen, + }) + + p.appendStmt(ir.EqualStmt{ + A: alen, + B: blen, + }) + + lkey := p.newLocal() + lval := p.newLocal() + bkeys := b.Keys() + + return p.planUnifyLocalObjectRec(a, 0, bkeys, b, lkey, lval, iter) +} + +func (p *Planner) planUnifyLocalObjectRec(a ir.Local, index int, keys []*ast.Term, b ast.Object, lkey, lval ir.Local, iter planiter) error { + + if index == len(keys) { + return iter() + } + + return p.planTerm(keys[index], func() error { + p.appendStmt(ir.AssignVarStmt{ + Source: p.ltarget, + Target: lkey, + }) + p.appendStmt(ir.DotStmt{ + Source: a, + Key: lkey, + Target: lval, + }) + return p.planUnifyLocal(lval, b.Get(keys[index]), func() error { + return p.planUnifyLocalObjectRec(a, index+1, keys, b, lkey, lval, iter) + }) + }) +} + +func (p *Planner) planUnifyArraysRec(a, b ast.Array, index int, iter planiter) error { + if index == len(a) { + return iter() + } + return p.planUnify(a[index], b[index], func() error { + return p.planUnifyArraysRec(a, b, index+1, iter) + }) +} + +func (p *Planner) planUnifyObjectsRec(a, b ast.Object, keys []*ast.Term, index int, iter planiter) error { + if index == len(keys) { + return iter() + } + + aval := a.Get(keys[index]) + bval := b.Get(keys[index]) + if aval == nil || bval == nil { + return nil + } + + return p.planUnify(aval, bval, func() error { + return p.planUnifyObjectsRec(a, b, keys, index+1, iter) + }) +} + func (p *Planner) planBinaryExpr(e *ast.Expr, iter binaryiter) error { return p.planTerm(e.Operand(0), func() error { a := p.ltarget diff --git a/internal/planner/planner_test.go b/internal/planner/planner_test.go index 12371d29ae..9df3c14931 100644 --- a/internal/planner/planner_test.go +++ b/internal/planner/planner_test.go @@ -62,6 +62,14 @@ func TestPlannerHelloWorld(t *testing.T) { note: "negation", queries: []string{"not input.x.y = 1"}, }, + { + note: "array ref pattern match", + queries: []string{"input.x = [1, [y]]"}, + }, + { + note: "arrays pattern match", + queries: []string{"[x, 3, [2]] = [1, 3, [y]]"}, + }, } for _, tc := range tests { diff --git a/internal/wasm/instruction/numeric.go b/internal/wasm/instruction/numeric.go index e110dcd603..422088a457 100644 --- a/internal/wasm/instruction/numeric.go +++ b/internal/wasm/instruction/numeric.go @@ -48,6 +48,16 @@ func (I32Eqz) Op() opcode.Opcode { return opcode.I32Eqz } +// I32Ne represents the WASM i32.ne instruction. +type I32Ne struct { + NoImmediateArgs +} + +// Op returns the opcode of the instruction. +func (I32Ne) Op() opcode.Opcode { + return opcode.I32Ne +} + // I32GtS represents the WASM i32.gt_s instruction. type I32GtS struct { NoImmediateArgs diff --git a/test/wasm/assets/001_eq.yaml b/test/wasm/assets/001_eq.yaml index fa7ce11540..960b922f08 100644 --- a/test/wasm/assets/001_eq.yaml +++ b/test/wasm/assets/001_eq.yaml @@ -39,3 +39,35 @@ cases: query: input.x = null input: {"x": false} return_code: 0 + - note: eq/array-empty + query: input.x = [] + input: {"x": []} + return_code: 1 + - note: eq/array-empty (negative) + query: input.x = [] + input: {"x": [1]} + return_code: 0 + - note: eq/array-non-empty + query: input.x = [1,2,3] + input: {"x": [1,2,3]} + return_code: 1 + - note: eq/array-non-empty (negative) + query: input.x = [1,2,3] + input: {"x": [1,3,2]} + return_code: 0 + - note: eq/object-empty + query: 'input.x = {}' + input: {"x": {}} + return_code: 1 + - note: eq/object-empty (negative) + query: 'input.x = {}' + input: {"x": {"a": 1}} + return_code: 0 + - note: eq/object-non-empty + query: 'input.x = {"a": 1, "b": 2}' + input: {"x": {"a": 1, "b": 2}} + return_code: 1 + - note: eq/object-non-empty (negative) + query: 'input.x = {"a": 1, "b": 2}' + input: {"x": {"a": 2, "b": 1}} + return_code: 0 diff --git a/test/wasm/assets/006_pattern_matching.yaml b/test/wasm/assets/006_pattern_matching.yaml new file mode 100644 index 0000000000..844dad6215 --- /dev/null +++ b/test/wasm/assets/006_pattern_matching.yaml @@ -0,0 +1,33 @@ +cases: + - note: match/array simple + query: "input.x = [y]; input.y = y" + input: {"x": [1], "y": 1} + return_code: 1 + - note: match/array simple (negative) + query: "input.x = [y]; input.y = y" + input: {"x": [1], "y": 2} + return_code: 0 + - note: match/array nested + query: "input.x = [[y], 1]; input.y = [y]" + input: {"x": [[0], 1], "y": [0]} + return_code: 1 + - note: match/array nested (negative) + query: "input.x = [[y], 1]; input.y = [y]" + input: {"x": [[0], 1], "y": [1]} + return_code: 0 + - note: match/object simple + query: 'input.x = {"a": y}; input.y = y' + input: {"x": {"a": 1}, "y": 1} + return_code: 1 + - note: match/object simple (negative) + query: 'input.x = {"a": y}; input.y = y' + input: {"x": {"a": 1}, "y": 2} + return_code: 0 + - note: match/object nested + query: 'input.x = {"a": {"b": y}, "c": 1}; input.y = {"a": y}' + input: {"x": {"a": {"b": 0}, "c": 1}, "y": {"a": 0}} + return_code: 1 + - note: match/object nested (negative) + query: 'input.x = {"a": {"b": y}, "c": 1}; input.y = {"a": y}' + input: {"x": {"a": {"b": 0}, "c": 1}, "y": {"a": 1}} + return_code: 0 diff --git a/wasm/src/value.c b/wasm/src/value.c index d0d9854196..34c45f3620 100644 --- a/wasm/src/value.c +++ b/wasm/src/value.c @@ -4,6 +4,11 @@ #define OPA_ARRAY_INITIAL_CAP (10) +int opa_value_type(opa_value *node) +{ + return node->type; +} + opa_value *opa_value_get_object(opa_object_t *obj, opa_value *key) { opa_object_elem_t *elem = opa_object_get(obj, key); @@ -398,11 +403,6 @@ int opa_value_compare(opa_value *a, opa_value *b) } } -int opa_value_not_equal(opa_value *a, opa_value *b) -{ - return opa_value_compare(a, b) != 0; -} - void opa_value_free(opa_value *node) { switch (node->type) @@ -463,6 +463,15 @@ opa_value *opa_boolean(int v) return &ret->hdr; } +opa_value *opa_number_size(size_t v) +{ + opa_number_t *ret = (opa_number_t *)opa_malloc(sizeof(opa_number_t)); + ret->hdr.type = OPA_NUMBER; + ret->is_float = 0; + ret->v.i = (long long)v; + return &ret->hdr; +} + opa_value *opa_number_int(long long v) { opa_number_t *ret = (opa_number_t *)opa_malloc(sizeof(opa_number_t)); @@ -555,6 +564,13 @@ void opa_value_boolean_set(opa_value *v, int b) ret->v = b; } +void opa_value_number_set_int(opa_value *v, long long i) +{ + opa_number_t *ret = opa_cast_number(v); + ret->is_float = 0; + ret->v.i = i; +} + void opa_array_free(opa_array_t *arr) { if (arr->elems != NULL) diff --git a/wasm/src/value.h b/wasm/src/value.h index 9cc19de6ae..3a9d6cd4cb 100644 --- a/wasm/src/value.h +++ b/wasm/src/value.h @@ -80,8 +80,8 @@ typedef int (*opa_compare_fn)(opa_value *, opa_value *t); #define opa_cast_array(v) container_of(v, opa_array_t, hdr) #define opa_cast_object(v) container_of(v, opa_object_t, hdr) +int opa_value_type(opa_value *node); int opa_value_compare(opa_value *a, opa_value *b); -int opa_value_not_equal(opa_value *a, opa_value *b); opa_value *opa_value_get(opa_value *node, opa_value *key); opa_value *opa_value_iter(opa_value *node, opa_value *prev); size_t opa_value_length(opa_value *node); @@ -94,6 +94,7 @@ int opa_value_boolean(opa_value *node); opa_value *opa_null(); opa_value *opa_boolean(int v); +opa_value *opa_number_size(size_t v); opa_value *opa_number_int(long long v); opa_value *opa_number_float(double v); opa_value *opa_string(const char *v, size_t len); @@ -103,6 +104,7 @@ opa_value *opa_array_with_cap(size_t cap); opa_value *opa_object(); void opa_value_boolean_set(opa_value *v, int b); +void opa_value_number_set_int(opa_value *v, long long i); void opa_array_free(opa_array_t *arr); void opa_array_append(opa_array_t *arr, opa_value *v); @@ -114,4 +116,4 @@ void opa_object_insert(opa_object_t *obj, opa_value *k, opa_value *v); opa_object_elem_t *opa_object_get(opa_object_t *obj, opa_value *key); opa_object_elem_t *opa_object_iter(opa_object_t *obj, opa_object_elem_t *prev); -#endif \ No newline at end of file +#endif diff --git a/wasm/tests/test.c b/wasm/tests/test.c index 7baa348d3c..9873e5c6b7 100644 --- a/wasm/tests/test.c +++ b/wasm/tests/test.c @@ -445,17 +445,17 @@ void test_opa_value_iter_object() opa_value *exp2 = opa_string_terminated("b"); opa_value *exp3 = NULL; - if (opa_value_not_equal(k1, exp1)) + if (opa_value_compare(k1, exp1) != 0) { test_fatal("object iter start did not return expected value"); } - if (opa_value_not_equal(k2, exp2)) + if (opa_value_compare(k2, exp2) != 0) { test_fatal("object iter second did not return expected value"); } - if (opa_value_not_equal(k3, exp3)) + if (opa_value_compare(k3, exp3) != 0) { test_fatal("object iter third did not return expected value"); } @@ -476,17 +476,17 @@ void test_opa_value_iter_array() opa_value *exp2 = opa_number_int(1); opa_value *exp3 = NULL; - if (opa_value_not_equal(k1, exp1)) + if (opa_value_compare(k1, exp1) != 0) { test_fatal("array iter start did not return expected value"); } - if (opa_value_not_equal(k2, exp2)) + if (opa_value_compare(k2, exp2) != 0) { test_fatal("array iter second did not return expected value"); } - if (opa_value_not_equal(k3, exp3)) + if (opa_value_compare(k3, exp3) != 0) { test_fatal("array iter third did not return expected value"); }