Nicolas Winkler преди 5 години
родител
ревизия
01579732e6
променени са 4 файла, в които са добавени 281 реда и са изтрити 132 реда
  1. 14 5
      libmandel/src/ClGenerators.cpp
  2. 1 0
      libmandel/src/Mandel.cpp
  3. 47 19
      libmandel/src/opencl/fixed128.cl
  4. 219 108
      libmandel/src/opencl/fixed128.h

+ 14 - 5
libmandel/src/ClGenerators.cpp

@@ -460,14 +460,18 @@ void ClGenerator128::generate(const mnd::MandelInfo& info, float* data)
     float pixelScaleY = float(info.view.height / info.bHeight);
 
     using ull = unsigned long long;
-    ull x1 = ull(double(info.view.x) * 0x100000000ULL);
+    ull x1 = ull(double(info.view.x) * 0x10000ULL);
     ull x2 = 0;
-    ull y1 = ull(double(info.view.y) * 0x100000000ULL);
+    ull y1 = ull(double(info.view.y) * 0x10000ULL);
     ull y2 = 0;
-    ull w1 = ull(double(pixelScaleX) * 0x100000000ULL);
+    ull w1 = ull(double(pixelScaleX) * 0x10000ULL);
     ull w2 = 0;
-    ull h1 = ull(double(pixelScaleY) * 0x100000000ULL);
+    ull h1 = ull(double(pixelScaleY) * 0x10000ULL);
     ull h2 = 0;
+    ull jx1 = ull(double(info.juliaX) * 0x10000ULL);
+    ull jx2 = 0;
+    ull jy1 = ull(double(info.juliaY) * 0x10000ULL);
+    ull jy2 = 0;
 
     kernel.setArg(0, buffer_A);
     kernel.setArg(1, int(info.bWidth));
@@ -481,6 +485,11 @@ void ClGenerator128::generate(const mnd::MandelInfo& info, float* data)
     kernel.setArg(9, ull(h2));
     kernel.setArg(10, int(info.maxIter));
     kernel.setArg(11, int(info.smooth ? 1 : 0));
+    kernel.setArg(12, int(info.julia ? 1 : 0));
+    kernel.setArg(13, ull(jx1));
+    kernel.setArg(14, ull(jx2));
+    kernel.setArg(15, ull(jy1));
+    kernel.setArg(16, ull(jy2));
 
     queue.enqueueNDRangeKernel(kernel, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
@@ -495,7 +504,7 @@ std::string ClGenerator128::getKernelCode(bool smooth) const
         std::istreambuf_iterator<char>());
     //fprintf(stderr, "%s\n", str);
     return str;*/
-    return getFixed512_cl();
+    return getFixed128_cl();
 }
 
 

+ 1 - 0
libmandel/src/Mandel.cpp

@@ -301,6 +301,7 @@ std::vector<std::unique_ptr<MandelDevice>> MandelContext::createDevices(void)
             try {
                 md.mandelGenerators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(md) });
                 md.mandelGenerators.insert({ GeneratorType::FIXED64, std::make_unique<ClGenerator64>(md) });
+                md.mandelGenerators.insert({ GeneratorType::FIXED128, std::make_unique<ClGenerator128>(md) });
                 md.mandelGenerators.insert({ GeneratorType::DOUBLE_FLOAT, std::make_unique<ClGeneratorDoubleFloat>(md) });
             }
             catch (const std::string& err) {

+ 47 - 19
libmandel/src/opencl/fixed128.cl

@@ -1,4 +1,18 @@
+ulong2 add(ulong2 a, ulong2 b) {
+    ulong lower = a[1] + b[1];
+    ulong upper = a[0] + b[0];
+    if (lower < a[1])
+        upper += 1;
+    return (ulong2)(upper, lower);
+}
 
+ulong2 sub(ulong2 a, ulong2 b) {
+    ulong lower = a[1] - b[1];
+    ulong upper = a[0] - b[0];
+    if (lower > a[1])
+        upper += 1;
+    return (ulong2)(upper, lower);
+}
 
 long2 mul(long2 a, long2 b) {
     long a0 = mul_hi(a[0], b[0]);
@@ -23,31 +37,45 @@ long2 mul(long2 a, long2 b) {
     long newUpper = (a0 << 16) + ((r2 >> 48) & 0xFFFF);
 }
 
+long2 mulInteger(long2 a, long b) {
+    long lo = a[1] * b;
+    long carry = mul_hi(a[1], b);
+    long hi = mad(a[0], b, carry);
+    return (long2)(hi, lo);
+}
+
 
 __kernel void iterate(__global float* A, const int width,
-                      ulong x, ulong y, ulong pw, ulong ph, int max, int smooth) {
+                      ulong x1, ulong x2, ulong y1, ulong y2,
+                      ulong pw1, ulong pw2, ulong ph1 ulong ph2,
+                      int max, int smooth, int julia,
+                      ulong jx1, ulong jx2, ulong jy1, ulong jy2) {
     int index = get_global_id(0);
-    long px = (index % width);
-    long py = (index / width);
+    int px = (index % width);
+    int py = (index / width);
 
-    long xl = x;
-    long yt = y;
-    long pixelScaleX = pw;
-    long pixelScaleY = ph;
+    long2 xl = (long2)(x1, x2);
+    long2 yt = (long2)(y1, y2);
+    long2 pixelScaleX = (long2)(pw1, pw2);
+    long2 pixelScaleY = (long2)(ph1, ph2);
 
-    long a = xl + pixelScaleX * px; // pixelScaleX * px + xl
-    long b = yt + pixelScaleY * py; // pixelScaleY * py + yt
-    long ca = a;
-    long cb = b;
+    long2 a = add(xl, mulInteger(pixelScaleX, px)); // pixelScaleX * px + xl
+    long2 b = add(yt, mulInteger(pixelScaleY, py))y; // pixelScaleY * py + yt
+    long2 ca = a;
+    long2 cb = b;
+    if(julia != 0) {
+        a = (long2)(jx1, jx2);
+        b = (long2)(jy1, jy2);
+    }
 
     int n = 0;
     while (n < max - 1) {
-        long aa = mul(a, a);
-        long bb = mul(b, b);
-        long ab = mul(a, b);
-        if (aa + bb > (16LL << 48)) break;
-        a = aa - bb + ca;
-        b = ab + ab + cb;
+        long2 aa = mul(a, a);
+        long2 bb = mul(b, b);
+        long2 ab = mul(a, b);
+        if (aa[0] + bb[0] > (16LL << 48)) break;
+        a = add(sub(aa, bb), ca);
+        b = add(add(ab, ab), cb);
         n++;
     }
 
@@ -56,8 +84,8 @@ __kernel void iterate(__global float* A, const int width,
         A[index] = max;
     else {
         if (smooth != 0) {
-            float aapprox = ((float) a) * (1.0f / (1LL << 48)); // 3.5527137e-15f;
-            float bapprox = ((float) b) * (1.0f / (1LL << 48)); // 3.5527137e-15f;
+            float aapprox = ((float) a[0]) * (1.0f / (1LL << 48)); // 3.5527137e-15f;
+            float bapprox = ((float) b[0]) * (1.0f / (1LL << 48)); // 3.5527137e-15f;
             A[index] = ((float) n) + 1 - log(log(aapprox * aapprox + bapprox * bapprox) / 2) / log(2.0f);
         }
         else

+ 219 - 108
libmandel/src/opencl/fixed128.h

@@ -1,115 +1,226 @@
 unsigned char fixed128_cl[] = {
-  0x0a, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x6d, 0x75, 0x6c, 0x28,
+  0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x64, 0x64, 0x28, 0x75,
+  0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x2c, 0x20, 0x75, 0x6c, 0x6f,
+  0x6e, 0x67, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x77, 0x65,
+  0x72, 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x31, 0x5d, 0x20, 0x2b, 0x20, 0x62,
+  0x5b, 0x31, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6c,
+  0x6f, 0x6e, 0x67, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x3d, 0x20,
+  0x61, 0x5b, 0x30, 0x5d, 0x20, 0x2b, 0x20, 0x62, 0x5b, 0x30, 0x5d, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6c, 0x6f,
+  0x77, 0x65, 0x72, 0x20, 0x3c, 0x20, 0x61, 0x5b, 0x31, 0x5d, 0x29, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x70, 0x70,
+  0x65, 0x72, 0x20, 0x2b, 0x3d, 0x20, 0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x75, 0x6c,
+  0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x75, 0x70, 0x70, 0x65, 0x72, 0x2c,
+  0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d,
+  0x0a, 0x0d, 0x0a, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x73, 0x75,
+  0x62, 0x28, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x2c, 0x20,
+  0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6c,
+  0x6f, 0x77, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x31, 0x5d, 0x20,
+  0x2d, 0x20, 0x62, 0x5b, 0x31, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72,
+  0x20, 0x3d, 0x20, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x2d, 0x20, 0x62, 0x5b,
+  0x30, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
+  0x28, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x3e, 0x20, 0x61, 0x5b, 0x31,
+  0x5d, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x2b, 0x3d, 0x20, 0x31, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
+  0x28, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x75, 0x70, 0x70,
+  0x65, 0x72, 0x2c, 0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x29, 0x3b, 0x0d,
+  0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20,
+  0x6d, 0x75, 0x6c, 0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x2c,
+  0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x30,
+  0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28, 0x61, 0x5b,
+  0x30, 0x5d, 0x2c, 0x20, 0x62, 0x5b, 0x30, 0x5d, 0x29, 0x3b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x62, 0x30, 0x20,
+  0x3d, 0x20, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x2a, 0x20, 0x62, 0x5b, 0x30,
+  0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67,
+  0x20, 0x62, 0x31, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69,
+  0x28, 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x62, 0x5b, 0x31, 0x5d, 0x29,
+  0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
+  0x62, 0x32, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28,
+  0x61, 0x5b, 0x31, 0x5d, 0x2c, 0x20, 0x62, 0x5b, 0x30, 0x5d, 0x29, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63,
+  0x30, 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x31, 0x5d, 0x20, 0x2a, 0x20, 0x62,
+  0x5b, 0x30, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
+  0x6e, 0x67, 0x20, 0x63, 0x31, 0x20, 0x3d, 0x20, 0x61, 0x5b, 0x30, 0x5d,
+  0x20, 0x2a, 0x20, 0x62, 0x5b, 0x31, 0x5d, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x32, 0x20, 0x3d, 0x20,
+  0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28, 0x61, 0x5b, 0x31, 0x5d, 0x2c,
+  0x20, 0x62, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x33, 0x20, 0x3d, 0x20, 0x6d,
+  0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28, 0x61, 0x5b, 0x31, 0x5d, 0x2c, 0x20,
+  0x62, 0x5b, 0x31, 0x5d, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x72, 0x72, 0x79,
+  0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
+  0x6f, 0x6e, 0x67, 0x20, 0x72, 0x31, 0x20, 0x3d, 0x20, 0x62, 0x30, 0x20,
+  0x2b, 0x20, 0x62, 0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
+  0x66, 0x20, 0x28, 0x72, 0x31, 0x20, 0x3c, 0x20, 0x62, 0x30, 0x29, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x72,
+  0x72, 0x79, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
+  0x6f, 0x6e, 0x67, 0x20, 0x72, 0x32, 0x20, 0x3d, 0x20, 0x72, 0x31, 0x20,
+  0x2b, 0x20, 0x62, 0x32, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
+  0x66, 0x20, 0x28, 0x72, 0x32, 0x20, 0x3c, 0x20, 0x72, 0x31, 0x29, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x61, 0x72,
+  0x72, 0x79, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x61, 0x30, 0x20, 0x2b, 0x3d, 0x20, 0x63, 0x61, 0x72, 0x72, 0x79,
+  0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e,
+  0x67, 0x20, 0x6e, 0x65, 0x77, 0x55, 0x70, 0x70, 0x65, 0x72, 0x20, 0x3d,
+  0x20, 0x28, 0x61, 0x30, 0x20, 0x3c, 0x3c, 0x20, 0x31, 0x36, 0x29, 0x20,
+  0x2b, 0x20, 0x28, 0x28, 0x72, 0x32, 0x20, 0x3e, 0x3e, 0x20, 0x34, 0x38,
+  0x29, 0x20, 0x26, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x46, 0x29, 0x3b,
+  0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x32,
+  0x20, 0x6d, 0x75, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28,
   0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x2c, 0x20, 0x6c, 0x6f, 0x6e,
-  0x67, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x3d,
-  0x20, 0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28, 0x61, 0x2c, 0x20, 0x62,
-  0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
-  0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20,
-  0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
-  0x6e, 0x20, 0x28, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x3c, 0x3c, 0x20,
-  0x31, 0x36, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x28, 0x6c, 0x6f, 0x77, 0x65,
-  0x72, 0x20, 0x3e, 0x3e, 0x20, 0x34, 0x38, 0x29, 0x20, 0x26, 0x20, 0x30,
-  0x78, 0x46, 0x46, 0x46, 0x46, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x0a,
-  0x5f, 0x5f, 0x6b, 0x65, 0x72, 0x6e, 0x65, 0x6c, 0x20, 0x76, 0x6f, 0x69,
-  0x64, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x5f, 0x5f,
-  0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
-  0x2a, 0x20, 0x41, 0x2c, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69,
-  0x6e, 0x74, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x0a, 0x20, 0x20,
+  0x67, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6c, 0x6f, 0x20, 0x3d, 0x20, 0x61, 0x5b,
+  0x31, 0x5d, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x61, 0x72, 0x72, 0x79, 0x20,
+  0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x5f, 0x68, 0x69, 0x28, 0x61, 0x5b, 0x31,
+  0x5d, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x68, 0x69, 0x20, 0x3d, 0x20, 0x6d, 0x61,
+  0x64, 0x28, 0x61, 0x5b, 0x30, 0x5d, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x63,
+  0x61, 0x72, 0x72, 0x79, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x6c, 0x6f, 0x6e, 0x67,
+  0x32, 0x29, 0x28, 0x68, 0x69, 0x2c, 0x20, 0x6c, 0x6f, 0x29, 0x3b, 0x0d,
+  0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x0d, 0x0a, 0x5f, 0x5f, 0x6b, 0x65,
+  0x72, 0x6e, 0x65, 0x6c, 0x20, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x69, 0x74,
+  0x65, 0x72, 0x61, 0x74, 0x65, 0x28, 0x5f, 0x5f, 0x67, 0x6c, 0x6f, 0x62,
+  0x61, 0x6c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x2a, 0x20, 0x41, 0x2c,
+  0x20, 0x63, 0x6f, 0x6e, 0x73, 0x74, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x77,
+  0x69, 0x64, 0x74, 0x68, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x78,
+  0x31, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x78, 0x32, 0x2c,
+  0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x79, 0x31, 0x2c, 0x20, 0x75,
+  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x79, 0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6c, 0x6f, 0x6e,
-  0x67, 0x20, 0x78, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x79,
-  0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x77, 0x2c, 0x20,
-  0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x68, 0x2c, 0x20, 0x69, 0x6e,
-  0x74, 0x20, 0x6d, 0x61, 0x78, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x73,
-  0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x69, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d,
-  0x20, 0x67, 0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f,
-  0x69, 0x64, 0x28, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
-  0x6f, 0x6e, 0x67, 0x20, 0x70, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e,
-  0x64, 0x65, 0x78, 0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70,
-  0x79, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2f,
-  0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x78, 0x6c, 0x20, 0x3d, 0x20,
-  0x78, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
-  0x79, 0x74, 0x20, 0x3d, 0x20, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
-  0x61, 0x6c, 0x65, 0x58, 0x20, 0x3d, 0x20, 0x70, 0x77, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x69, 0x78, 0x65,
-  0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x3d, 0x20, 0x70, 0x68,
-  0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
-  0x61, 0x20, 0x3d, 0x20, 0x78, 0x6c, 0x20, 0x2b, 0x20, 0x70, 0x69, 0x78,
-  0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2a, 0x20, 0x70,
-  0x78, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x67, 0x20, 0x70, 0x77, 0x31, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67,
+  0x20, 0x70, 0x77, 0x32, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
+  0x70, 0x68, 0x31, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x70, 0x68,
+  0x32, 0x2c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6d, 0x61, 0x78, 0x2c, 0x20, 0x69,
+  0x6e, 0x74, 0x20, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x2c, 0x20, 0x69,
+  0x6e, 0x74, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x2c, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x75, 0x6c, 0x6f,
+  0x6e, 0x67, 0x20, 0x6a, 0x78, 0x31, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e,
+  0x67, 0x20, 0x6a, 0x78, 0x32, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67,
+  0x20, 0x6a, 0x79, 0x31, 0x2c, 0x20, 0x75, 0x6c, 0x6f, 0x6e, 0x67, 0x20,
+  0x6a, 0x79, 0x32, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x69, 0x6e, 0x74, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20,
+  0x67, 0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69,
+  0x64, 0x28, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69,
+  0x6e, 0x74, 0x20, 0x70, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, 0x64,
+  0x65, 0x78, 0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x79,
+  0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2f, 0x20,
+  0x77, 0x69, 0x64, 0x74, 0x68, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x78, 0x6c, 0x20,
+  0x3d, 0x20, 0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x78, 0x31,
+  0x2c, 0x20, 0x78, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x79, 0x74, 0x20, 0x3d, 0x20, 0x28,
+  0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x79, 0x31, 0x2c, 0x20, 0x79,
+  0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e,
+  0x67, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c,
+  0x65, 0x58, 0x20, 0x3d, 0x20, 0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29,
+  0x28, 0x70, 0x77, 0x31, 0x2c, 0x20, 0x70, 0x77, 0x32, 0x29, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x70,
+  0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x3d,
+  0x20, 0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x70, 0x68, 0x31,
+  0x2c, 0x20, 0x70, 0x68, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x20, 0x3d,
+  0x20, 0x61, 0x64, 0x64, 0x28, 0x78, 0x6c, 0x2c, 0x20, 0x6d, 0x75, 0x6c,
+  0x49, 0x6e, 0x74, 0x65, 0x67, 0x65, 0x72, 0x28, 0x70, 0x69, 0x78, 0x65,
+  0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20, 0x70, 0x78, 0x29,
+  0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
   0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2a, 0x20, 0x70, 0x78, 0x20, 0x2b,
-  0x20, 0x78, 0x6c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67,
-  0x20, 0x62, 0x20, 0x3d, 0x20, 0x79, 0x74, 0x20, 0x2b, 0x20, 0x70, 0x69,
-  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x2a, 0x20,
-  0x70, 0x79, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c,
-  0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x2a, 0x20, 0x70, 0x79, 0x20,
-  0x2b, 0x20, 0x79, 0x74, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e,
-  0x67, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x62, 0x20, 0x3d, 0x20,
-  0x62, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20,
-  0x6e, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77,
-  0x68, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61,
-  0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x61,
+  0x20, 0x78, 0x6c, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e,
+  0x67, 0x32, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x79,
+  0x74, 0x2c, 0x20, 0x6d, 0x75, 0x6c, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x65,
+  0x72, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65,
+  0x59, 0x2c, 0x20, 0x70, 0x79, 0x29, 0x29, 0x79, 0x3b, 0x20, 0x2f, 0x2f,
+  0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59,
+  0x20, 0x2a, 0x20, 0x70, 0x79, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x63, 0x61,
+  0x20, 0x3d, 0x20, 0x61, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c,
+  0x6f, 0x6e, 0x67, 0x32, 0x20, 0x63, 0x62, 0x20, 0x3d, 0x20, 0x62, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x28, 0x6a, 0x75, 0x6c,
+  0x69, 0x61, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20,
+  0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x29, 0x28, 0x6a, 0x78, 0x31, 0x2c,
+  0x20, 0x6a, 0x78, 0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x28, 0x6c, 0x6f, 0x6e,
+  0x67, 0x32, 0x29, 0x28, 0x6a, 0x79, 0x31, 0x2c, 0x20, 0x6a, 0x79, 0x32,
+  0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6e, 0x20, 0x3d,
+  0x20, 0x30, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69,
+  0x6c, 0x65, 0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78, 0x20,
+  0x2d, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20, 0x61, 0x61,
   0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x29,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f,
-  0x6e, 0x67, 0x20, 0x62, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28,
-  0x62, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x62, 0x20, 0x3d,
-  0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
-  0x61, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x62, 0x20, 0x3e, 0x20, 0x28, 0x31,
-  0x36, 0x4c, 0x4c, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x29, 0x29, 0x20,
-  0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x61, 0x20, 0x2d, 0x20,
-  0x62, 0x62, 0x20, 0x2b, 0x20, 0x63, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x62, 0x20,
-  0x2b, 0x20, 0x61, 0x62, 0x20, 0x2b, 0x20, 0x63, 0x62, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f,
-  0x2f, 0x20, 0x4e, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f,
-  0x67, 0x20, 0x28, 0x6c, 0x6f, 0x67, 0x20, 0x20, 0x7c, 0x5a, 0x28, 0x4e,
-  0x29, 0x7c, 0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x32, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e, 0x3d,
-  0x20, 0x6d, 0x61, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65,
-  0x78, 0x5d, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f,
-  0x6f, 0x74, 0x68, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x61, 0x70, 0x70, 0x72, 0x6f,
-  0x78, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29,
-  0x20, 0x61, 0x29, 0x20, 0x2a, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x66, 0x20,
-  0x2f, 0x20, 0x28, 0x31, 0x4c, 0x4c, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38,
-  0x29, 0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x33, 0x2e, 0x35, 0x35, 0x32,
-  0x37, 0x31, 0x33, 0x37, 0x65, 0x2d, 0x31, 0x35, 0x66, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78,
-  0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20,
-  0x62, 0x29, 0x20, 0x2a, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x66, 0x20, 0x2f,
-  0x20, 0x28, 0x31, 0x4c, 0x4c, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x29,
-  0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20, 0x33, 0x2e, 0x35, 0x35, 0x32, 0x37,
-  0x31, 0x33, 0x37, 0x65, 0x2d, 0x31, 0x35, 0x66, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b,
-  0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31,
-  0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c, 0x6f, 0x67, 0x28, 0x61,
-  0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x20, 0x2a, 0x20, 0x61, 0x61, 0x70,
-  0x70, 0x72, 0x6f, 0x78, 0x20, 0x2b, 0x20, 0x62, 0x61, 0x70, 0x70, 0x72,
-  0x6f, 0x78, 0x20, 0x2a, 0x20, 0x62, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78,
-  0x29, 0x20, 0x2f, 0x20, 0x32, 0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67,
-  0x28, 0x32, 0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64,
-  0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x29, 0x6e, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
-  0x7d, 0x0a
+  0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c,
+  0x6f, 0x6e, 0x67, 0x32, 0x20, 0x62, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75,
+  0x6c, 0x28, 0x62, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x32, 0x20,
+  0x61, 0x62, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20,
+  0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x5b, 0x30, 0x5d, 0x20, 0x2b,
+  0x20, 0x62, 0x62, 0x5b, 0x30, 0x5d, 0x20, 0x3e, 0x20, 0x28, 0x31, 0x36,
+  0x4c, 0x4c, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x29, 0x29, 0x20, 0x62,
+  0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x73,
+  0x75, 0x62, 0x28, 0x61, 0x61, 0x2c, 0x20, 0x62, 0x62, 0x29, 0x2c, 0x20,
+  0x63, 0x61, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x61, 0x64,
+  0x64, 0x28, 0x61, 0x62, 0x2c, 0x20, 0x61, 0x62, 0x29, 0x2c, 0x20, 0x63,
+  0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x4e,
+  0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x28,
+  0x6c, 0x6f, 0x67, 0x20, 0x20, 0x7c, 0x5a, 0x28, 0x4e, 0x29, 0x7c, 0x29,
+  0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x20, 0x32, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e, 0x3d, 0x20, 0x6d,
+  0x61, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x0d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78,
+  0x5d, 0x20, 0x3d, 0x20, 0x6d, 0x61, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x73, 0x6d,
+  0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x29, 0x20, 0x7b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x61, 0x70, 0x70,
+  0x72, 0x6f, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x29, 0x20, 0x61, 0x5b, 0x30, 0x5d, 0x29, 0x20, 0x2a, 0x20, 0x28,
+  0x31, 0x2e, 0x30, 0x66, 0x20, 0x2f, 0x20, 0x28, 0x31, 0x4c, 0x4c, 0x20,
+  0x3c, 0x3c, 0x20, 0x34, 0x38, 0x29, 0x29, 0x3b, 0x20, 0x2f, 0x2f, 0x20,
+  0x33, 0x2e, 0x35, 0x35, 0x32, 0x37, 0x31, 0x33, 0x37, 0x65, 0x2d, 0x31,
+  0x35, 0x66, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62,
+  0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20, 0x62, 0x5b, 0x30, 0x5d, 0x29, 0x20,
+  0x2a, 0x20, 0x28, 0x31, 0x2e, 0x30, 0x66, 0x20, 0x2f, 0x20, 0x28, 0x31,
+  0x4c, 0x4c, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x29, 0x29, 0x3b, 0x20,
+  0x2f, 0x2f, 0x20, 0x33, 0x2e, 0x35, 0x35, 0x32, 0x37, 0x31, 0x33, 0x37,
+  0x65, 0x2d, 0x31, 0x35, 0x66, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e,
+  0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x29, 0x20, 0x6e, 0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d,
+  0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c, 0x6f, 0x67, 0x28, 0x61, 0x61, 0x70,
+  0x70, 0x72, 0x6f, 0x78, 0x20, 0x2a, 0x20, 0x61, 0x61, 0x70, 0x70, 0x72,
+  0x6f, 0x78, 0x20, 0x2b, 0x20, 0x62, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78,
+  0x20, 0x2a, 0x20, 0x62, 0x61, 0x70, 0x70, 0x72, 0x6f, 0x78, 0x29, 0x20,
+  0x2f, 0x20, 0x32, 0x29, 0x20, 0x2f, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x32,
+  0x2e, 0x30, 0x66, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e,
+  0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x29, 0x6e, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x7d, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a
 };
-unsigned int fixed128_cl_len = 1334;
+unsigned int fixed128_cl_len = 2670;