Nicolas Winkler 5 år sedan
förälder
incheckning
45c5dccaf2

+ 13 - 29
libmandel/src/CpuGeneratorsAVXFMA.cpp

@@ -91,15 +91,15 @@ void CpuGenerator<float, mnd::X86_AVX_FMA, parallel>::generate(const mnd::Mandel
                     __m256 ab = _mm256_mul_ps(a, b);
                     __m256 ab2 = _mm256_mul_ps(a2, b2);
                     __m256 ab3 = _mm256_mul_ps(a3, b3);
-                    a = _mm256_add_ps(_mm256_fmsub_ps(a, a, bb), cx);
-                    a2 = _mm256_add_ps(_mm256_fmsub_ps(a2, a2, bb2), cx2);
-                    a3 = _mm256_add_ps(_mm256_fmsub_ps(a3, a3, bb3), cx3);
                     b = _mm256_fmadd_ps(two, ab, cy);
                     b2 = _mm256_fmadd_ps(two, ab2, cy);
                     b3 = _mm256_fmadd_ps(two, ab3, cy);
                     __m256 cmp = _mm256_cmp_ps(_mm256_fmadd_ps(a, a, bb), threshold, _CMP_LE_OQ);
                     __m256 cmp2 = _mm256_cmp_ps(_mm256_fmadd_ps(a2, a2, bb2), threshold, _CMP_LE_OQ);
                     __m256 cmp3 = _mm256_cmp_ps(_mm256_fmadd_ps(a3, a3, bb3), threshold, _CMP_LE_OQ);
+                    a = _mm256_add_ps(_mm256_fmsub_ps(a, a, bb), cx);
+                    a2 = _mm256_add_ps(_mm256_fmsub_ps(a2, a2, bb2), cx2);
+                    a3 = _mm256_add_ps(_mm256_fmsub_ps(a3, a3, bb3), cx3);
                     resultsa = _mm256_or_ps(_mm256_andnot_ps(cmp, resultsa), _mm256_and_ps(cmp, a));
                     resultsb = _mm256_or_ps(_mm256_andnot_ps(cmp, resultsb), _mm256_and_ps(cmp, b));
                     resultsa2 = _mm256_or_ps(_mm256_andnot_ps(cmp2, resultsa2), _mm256_and_ps(cmp2, a2));
@@ -125,15 +125,15 @@ void CpuGenerator<float, mnd::X86_AVX_FMA, parallel>::generate(const mnd::Mandel
                     __m256 ab = _mm256_mul_ps(a, b);
                     __m256 ab2 = _mm256_mul_ps(a2, b2);
                     __m256 ab3 = _mm256_mul_ps(a3, b3);
+                    __m256 cmp = _mm256_cmp_ps(_mm256_fmadd_ps(a, a, bb), threshold, _CMP_LE_OQ);
+                    __m256 cmp2 = _mm256_cmp_ps(_mm256_fmadd_ps(a2, a2, bb2), threshold, _CMP_LE_OQ);
+                    __m256 cmp3 = _mm256_cmp_ps(_mm256_fmadd_ps(a3, a3, bb3), threshold, _CMP_LE_OQ);
                     a = _mm256_add_ps(_mm256_fmsub_ps(a, a, bb), cx);
                     a2 = _mm256_add_ps(_mm256_fmsub_ps(a2, a2, bb2), cx2);
                     a3 = _mm256_add_ps(_mm256_fmsub_ps(a3, a3, bb3), cx3);
                     b = _mm256_fmadd_ps(two, ab, cy);
                     b2 = _mm256_fmadd_ps(two, ab2, cy);
                     b3 = _mm256_fmadd_ps(two, ab3, cy);
-                    __m256 cmp = _mm256_cmp_ps(_mm256_fmadd_ps(a, a, bb), threshold, _CMP_LE_OQ);
-                    __m256 cmp2 = _mm256_cmp_ps(_mm256_fmadd_ps(a2, a2, bb2), threshold, _CMP_LE_OQ);
-                    __m256 cmp3 = _mm256_cmp_ps(_mm256_fmadd_ps(a3, a3, bb3), threshold, _CMP_LE_OQ);
                     adder = _mm256_and_ps(adder, cmp);
                     counter = _mm256_add_ps(counter, adder);
                     adder2 = _mm256_and_ps(adder2, cmp2);
@@ -241,14 +241,14 @@ void CpuGenerator<double, mnd::X86_AVX_FMA, parallel>::generate(const mnd::Mande
                 __m256d bb = _mm256_mul_pd(b, b);
                 __m256d ab2 = _mm256_mul_pd(a2, b2);
                 __m256d bb2 = _mm256_mul_pd(b2, b2);
+                __m256d cmp = _mm256_cmp_pd(_mm256_fmadd_pd(a, a, bb), threshold, _CMP_LE_OQ);
+                __m256d cmp2 = _mm256_cmp_pd(_mm256_fmadd_pd(a2, a2, bb2), threshold, _CMP_LE_OQ);
                 a = _mm256_fmsub_pd(a, a, bb);
                 a = _mm256_add_pd(a, cx);
                 a2 = _mm256_fmsub_pd(a2, a2, bb2);
                 a2 = _mm256_add_pd(a2, cx2);
                 b = _mm256_fmadd_pd(two, ab, cy);
                 b2 = _mm256_fmadd_pd(two, ab2, cy);
-                __m256d cmp = _mm256_cmp_pd(_mm256_fmadd_pd(a, a, bb), threshold, _CMP_LE_OQ);
-                __m256d cmp2 = _mm256_cmp_pd(_mm256_fmadd_pd(a2, a2, bb2), threshold, _CMP_LE_OQ);
                 if (info.smooth) {
                     resultsa = _mm256_or_pd(_mm256_andnot_pd(cmp, resultsa), _mm256_and_pd(cmp, a));
                     resultsb = _mm256_or_pd(_mm256_andnot_pd(cmp, resultsb), _mm256_and_pd(cmp, b));
@@ -341,32 +341,12 @@ static inline VecPair twoDiff(__m256d a, __m256d b)
     return { s, e };
 }
 
-/*
-static inline VecPair split(__m256d a)
-{
-    static const __m256d SPLIT_THRESH = { 6.69692879491417e+299, 6.69692879491417e+299, 6.69692879491417e+299, 6.69692879491417e+299 };
-    static const __m256d MINUS_SPLIT_THRESH = { -6.69692879491417e+299, -6.69692879491417e+299, -6.69692879491417e+299, -6.69692879491417e+299 };
-    static const __m256d SPLITTER = { 134217729.0, 134217729.0, 134217729.0, 134217729.0};
-    __m256d temp;
-    __m256i cmp1 = _mm256_castpd_si256(_mm256_cmp_pd(a, SPLIT_THRESH, _CMP_GT_OQ));
-    __m256i cmp2 = _mm256_castpd_si256(_mm256_cmp_pd(a, MINUS_SPLIT_THRESH, _CMP_LT_OQ));
-    __m256i cmp = _mm256_or_si256
-}*/
 
 static inline VecPair twoProd(__m256d a, __m256d b)
 {
-//#ifdef CPUID_FMA
     __m256d p = _mm256_mul_pd(a, b);
     __m256d e = _mm256_fmsub_pd(a, b, p);
     return { p, e };
-//#else
-/*    double a_hi, a_lo, b_hi, b_lo;
-    __m256d p = _mm256_mul_ps(a, b);
-    split(a, a_hi, a_lo);
-    split(b, b_hi, b_lo);
-    err = ((a_hi * b_hi - p) + a_hi * b_lo + a_lo * b_hi) + a_lo * b_lo;
-    return p;*/
-//#endif
 }
 
 struct AvxDoubleDouble
@@ -405,6 +385,7 @@ struct AvxDoubleDouble
     }
 };
 
+
 template<bool parallel>
 void CpuGenerator<mnd::DoubleDouble, mnd::X86_AVX_FMA, parallel>::generate(const mnd::MandelInfo& info, float* data)
 {
@@ -468,7 +449,7 @@ void CpuGenerator<mnd::DoubleDouble, mnd::X86_AVX_FMA, parallel>::generate(const
                 AvxDoubleDouble bb = b * b;
                 AvxDoubleDouble abab = a * b; abab = abab + abab;
                 a = aa - bb + cx;
-                b = abab + cx;
+                b = abab + cy;
                 __m256d cmp = _mm256_cmp_pd(_mm256_add_pd(aa.x[0], bb.x[0]), threshold, _CMP_LE_OQ);
                 if (info.smooth) {
                     resultsa = _mm256_or_pd(_mm256_andnot_pd(cmp, resultsa), _mm256_and_pd(cmp, a.x[0]));
@@ -493,6 +474,7 @@ void CpuGenerator<mnd::DoubleDouble, mnd::X86_AVX_FMA, parallel>::generate(const
             double* resa = (double*) &resultsa;
             double* resb = (double*) &resultsb;
             _mm256_store_pd(ftRes, counter);
+
             for (int k = 0; k < 4 && i + k < info.bWidth; k++) {
                 if (info.smooth)
                     data[i + k + j * info.bWidth] = ftRes[k] <= 0 ? info.maxIter :
@@ -505,3 +487,5 @@ void CpuGenerator<mnd::DoubleDouble, mnd::X86_AVX_FMA, parallel>::generate(const
     }
 }
 
+
+

+ 85 - 26
libmandel/src/CpuGeneratorsSSE2.cpp

@@ -22,46 +22,71 @@ void CpuGenerator<float, mnd::X86_SSE2, parallel>::generate(const mnd::MandelInf
     using T = float;
     const MandelViewport& view = info.view;
 
+    const float dppf = float(view.width / info.bWidth);
+    const float viewxf = float(view.x);
+    __m128 viewx = { viewxf, viewxf, viewxf, viewxf };
+    __m128 dpp = { dppf, dppf, dppf, dppf };
+
+    T jX = mnd::convert<T>(info.juliaX);
+    T jY = mnd::convert<T>(info.juliaY);
+    __m128 juliaX = { jX, jX, jX, jX };
+    __m128 juliaY = { jY, jY, jY, jY };
+
     if constexpr(parallel)
         omp_set_num_threads(omp_get_num_procs());
 #pragma omp parallel for schedule(static, 1) if (parallel)
     for (long j = 0; j < info.bHeight; j++) {
         T y = T(view.y) + T(j) * T(view.height / info.bHeight);
+        __m128 ys = {y, y, y, y};
         long i = 0;
-        for (i; i < info.bWidth; i += 4) {
-            __m128 xs = {
-                float(view.x + double(i) * view.width / info.bWidth),
-                float(view.x + double(i + 1) * view.width / info.bWidth),
-                float(view.x + double(i + 2) * view.width / info.bWidth),
-                float(view.x + double(i + 3) * view.width / info.bWidth)
-            };
+        for (i; i < info.bWidth; i += 8) {
+            __m128 pixc = { float(i), float(i + 1), float(i + 2), float(i + 3) };
+            __m128 pixc2 = { float(i + 4), float(i + 5), float(i + 6), float(i + 7) };
+            __m128 xs = _mm_add_ps(_mm_mul_ps(dpp, pixc), viewx);
+            __m128 xs2 = _mm_add_ps(_mm_mul_ps(dpp, pixc2), viewx);
 
             __m128 counter = { 0, 0, 0, 0 };
             __m128 adder = { 1, 1, 1, 1 };
+            __m128 counter2 = { 0, 0, 0, 0 };
+            __m128 adder2 = { 1, 1, 1, 1 };
 
             __m128 threshold = { 16.0f, 16.0f, 16.0f, 16.0f };
 
-            __m128 ys = {y, y, y, y};
             __m128 a = xs;
             __m128 b = ys;
+            __m128 a2 = xs2;
+            __m128 b2 = ys;
 
             __m128 resulta = { 0, 0, 0, 0 };
             __m128 resultb = { 0, 0, 0, 0 };
+            __m128 resulta2 = { 0, 0, 0, 0 };
+            __m128 resultb2 = { 0, 0, 0, 0 };
 
             for (int k = 0; k < info.maxIter; k++) {
                 __m128 aa = _mm_mul_ps(a, a);
+                __m128 aa2 = _mm_mul_ps(a2, a2);
                 __m128 bb = _mm_mul_ps(b, b);
+                __m128 bb2 = _mm_mul_ps(b2, b2);
                 __m128 abab = _mm_mul_ps(a, b); abab = _mm_add_ps(abab, abab);
+                __m128 abab2 = _mm_mul_ps(a2, b2); abab2 = _mm_add_ps(abab2, abab2);
                 a = _mm_add_ps(_mm_sub_ps(aa, bb), xs);
                 b = _mm_add_ps(abab, ys);
+                a2 = _mm_add_ps(_mm_sub_ps(aa2, bb2), xs2);
+                b2 = _mm_add_ps(abab2, ys);
                 __m128 cmp = _mm_cmple_ps(_mm_add_ps(aa, bb), threshold);
+                __m128 cmp2 = _mm_cmple_ps(_mm_add_ps(aa2, bb2), threshold);
                 if (info.smooth) {
                     resulta = _mm_or_ps(_mm_andnot_ps(cmp, resulta), _mm_and_ps(cmp, a));
                     resultb = _mm_or_ps(_mm_andnot_ps(cmp, resultb), _mm_and_ps(cmp, b));
+                    resulta2 = _mm_or_ps(_mm_andnot_ps(cmp2, resulta2), _mm_and_ps(cmp2, a2));
+                    resultb2 = _mm_or_ps(_mm_andnot_ps(cmp2, resultb2), _mm_and_ps(cmp2, b2));
                 }
                 adder = _mm_and_ps(adder, cmp);
                 counter = _mm_add_ps(counter, adder);
-                if (_mm_movemask_epi8(_mm_castps_si128(cmp)) == 0) {
+                adder2 = _mm_and_ps(adder2, cmp2);
+                counter2 = _mm_add_ps(counter2, adder2);
+                if ((k & 0x7) == 0 && _mm_movemask_epi8(_mm_castps_si128(cmp)) == 0 &&
+                    _mm_movemask_epi8(_mm_castps_si128(cmp2)) == 0) {
                     break;
                 }
             }
@@ -73,15 +98,18 @@ void CpuGenerator<float, mnd::X86_SSE2, parallel>::generate(const mnd::MandelInf
                 return static_cast<float*>(aligned);
             };
 
-            float resData[32];
+            float resData[64];
             float* ftRes = alignVec(resData);
-            float* resa = ftRes + 4;
-            float* resb = ftRes + 8;
+            float* resa = ftRes + 8;
+            float* resb = ftRes + 16;
 
             _mm_store_ps(ftRes, counter);
+            _mm_store_ps(ftRes + 4, counter2);
             _mm_store_ps(resa, resulta);
+            _mm_store_ps(resa + 4, resulta2);
             _mm_store_ps(resb, resultb);
-            for (int k = 0; k < 4 && i + k < info.bWidth; k++) {
+            _mm_store_ps(resb + 4, resultb2);
+            for (int k = 0; k < 8 && i + k < info.bWidth; k++) {
                 if (info.smooth)
                     data[i + k + j * info.bWidth] = ftRes[k] <= 0 ? info.maxIter :
                     ftRes[k] >= info.maxIter ? info.maxIter :
@@ -99,43 +127,71 @@ void CpuGenerator<double, mnd::X86_SSE2, parallel>::generate(const mnd::MandelIn
 {
     using T = double;
     const MandelViewport& view = info.view;
+
+    const double dppf = double(view.width / info.bWidth);
+    const double viewxf = double(view.x);
+    __m128d viewx = { viewxf, viewxf };
+    __m128d dpp = { dppf, dppf };
+
+    T jX = mnd::convert<T>(info.juliaX);
+    T jY = mnd::convert<T>(info.juliaY);
+    __m128d juliaX = { jX, jX };
+    __m128d juliaY = { jY, jY };
+
     if constexpr(parallel)
         omp_set_num_threads(omp_get_num_procs());
 #pragma omp parallel for schedule(static, 1) if (parallel)
     for (long j = 0; j < info.bHeight; j++) {
         T y = T(view.y) + T(j) * T(view.height / info.bHeight);
+        __m128d ys = { y, y };
         long i = 0;
-        for (i; i < info.bWidth; i += 2) {
-            __m128d xs = {
-                double(view.x + double(i) * view.width / info.bWidth),
-                double(view.x + double(i + 1) * view.width / info.bWidth)
-            };
+        for (i; i < info.bWidth; i += 4) {
+            __m128d pixc = { double(i), double(i + 1) };
+            __m128d pixc2 = { double(i + 2), double(i + 3) };
+            __m128d xs = _mm_add_pd(_mm_mul_pd(dpp, pixc), viewx);
+            __m128d xs2 = _mm_add_pd(_mm_mul_pd(dpp, pixc2), viewx);
 
             __m128d counter = { 0, 0 };
             __m128d adder = { 1, 1 };
+            __m128d counter2 = { 0, 0 };
+            __m128d adder2 = { 1, 1 };
 
             __m128d threshold = { 16.0f, 16.0f };
 
-            __m128d ys = { y, y };
             __m128d a = xs;
             __m128d b = ys;
+            __m128d a2 = xs2;
+            __m128d b2 = ys;
             __m128d resulta = { 0, 0 };
             __m128d resultb = { 0, 0 };
+            __m128d resulta2 = { 0, 0 };
+            __m128d resultb2 = { 0, 0 };
 
             for (int k = 0; k < info.maxIter; k++) {
                 __m128d aa = _mm_mul_pd(a, a);
+                __m128d aa2 = _mm_mul_pd(a2, a2);
                 __m128d bb = _mm_mul_pd(b, b);
+                __m128d bb2 = _mm_mul_pd(b2, b2);
                 __m128d abab = _mm_mul_pd(a, b); abab = _mm_add_pd(abab, abab);
+                __m128d abab2 = _mm_mul_pd(a2, b2); abab2 = _mm_add_pd(abab2, abab2);
                 a = _mm_add_pd(_mm_sub_pd(aa, bb), xs);
                 b = _mm_add_pd(abab, ys);
+                a2 = _mm_add_pd(_mm_sub_pd(aa2, bb2), xs2);
+                b2 = _mm_add_pd(abab2, ys);
                 __m128d cmp = _mm_cmple_pd(_mm_add_pd(aa, bb), threshold);
+                __m128d cmp2 = _mm_cmple_pd(_mm_add_pd(aa2, bb2), threshold);
                 if (info.smooth) {
                     resulta = _mm_or_pd(_mm_andnot_pd(cmp, resulta), _mm_and_pd(cmp, a));
                     resultb = _mm_or_pd(_mm_andnot_pd(cmp, resultb), _mm_and_pd(cmp, b));
+                    resulta2 = _mm_or_pd(_mm_andnot_pd(cmp2, resulta2), _mm_and_pd(cmp2, a2));
+                    resultb2 = _mm_or_pd(_mm_andnot_pd(cmp2, resultb2), _mm_and_pd(cmp2, b2));
                 }
                 adder = _mm_and_pd(adder, cmp);
                 counter = _mm_add_pd(counter, adder);
-                if (_mm_movemask_epi8(_mm_castpd_si128(cmp)) == 0) {
+                adder2 = _mm_and_pd(adder2, cmp2);
+                counter2 = _mm_add_pd(counter2, adder2);
+                if ((k & 0x7 == 0) && _mm_movemask_epi8(_mm_castpd_si128(cmp)) == 0 &&
+                    _mm_movemask_epi8(_mm_castpd_si128(cmp)) == 0) {
                     break;
                 }
             }
@@ -147,18 +203,21 @@ void CpuGenerator<double, mnd::X86_SSE2, parallel>::generate(const mnd::MandelIn
                 return static_cast<double*>(aligned);
             };
 
-            double resData[16];
+            double resData[24];
             double* ftRes = alignVec(resData);
-            double* resa = ftRes + 2;
-            double* resb = ftRes + 4;
+            double* resa = ftRes + 4;
+            double* resb = ftRes + 8;
 
             _mm_store_pd(ftRes, counter);
+            _mm_store_pd(ftRes + 2, counter2);
             _mm_store_pd(resa, resulta);
+            _mm_store_pd(resa + 2, resulta2);
             _mm_store_pd(resb, resultb);
-            for (int k = 0; k < 2 && i + k < info.bWidth; k++)
-                data[i + k + j * info.bWidth] = ftRes[k] > 0 ? ftRes[k] : info.maxIter;
+            _mm_store_pd(resb + 2, resultb2);
+            //for (int k = 0; k < 2 && i + k < info.bWidth; k++)
+            //    data[i + k + j * info.bWidth] = ftRes[k] > 0 ? ftRes[k] : info.maxIter;
 
-            for (int k = 0; k < 2 && i + k < info.bWidth; k++) {
+            for (int k = 0; k < 4 && i + k < info.bWidth; k++) {
                 if (info.smooth)
                     data[i + k + j * info.bWidth] = ftRes[k] <= 0 ? info.maxIter :
                     ftRes[k] >= info.maxIter ? info.maxIter :

+ 1 - 0
libmandel/src/opencl/float.cl

@@ -1,3 +1,4 @@
+
 __kernel void iterate(__global float* A, const int width, float xl, float yt, float pixelScaleX, float pixelScaleY, int max, int smooth, int julia, float juliaX, float juliaY) {
    int index = get_global_id(0);
    int x = index % width;

+ 209 - 209
libmandel/src/opencl/float.h

@@ -1,217 +1,217 @@
 unsigned char float_cl[] = {
-  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, 0x20, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x20, 0x79, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
-  0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c,
-  0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 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, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a, 0x75,
-  0x6c, 0x69, 0x61, 0x58, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
-  0x6a, 0x75, 0x6c, 0x69, 0x61, 0x59, 0x29, 0x20, 0x7b, 0x0a, 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, 0x69, 0x6e,
-  0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20,
-  0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x69, 0x6e, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65,
-  0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x20, 0x3d, 0x20,
-  0x78, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61,
-  0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x79,
-  0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c,
-  0x65, 0x59, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20, 0x6a,
-  0x75, 0x6c, 0x69, 0x61, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x3f, 0x20,
-  0x6a, 0x75, 0x6c, 0x69, 0x61, 0x58, 0x20, 0x3a, 0x20, 0x61, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x62, 0x20,
-  0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x21, 0x3d, 0x20, 0x30,
-  0x20, 0x3f, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x59, 0x20, 0x3a, 0x20,
-  0x62, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6e,
-  0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x61, 0x20, 0x3d,
-  0x20, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x62, 0x20,
-  0x3d, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x62,
-  0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x61, 0x20,
-  0x2b, 0x20, 0x62, 0x62, 0x20, 0x3e, 0x20, 0x31, 0x36, 0x29, 0x20, 0x62,
-  0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 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, 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, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x7d,
-  0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e, 0x3d,
-  0x20, 0x6d, 0x61, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, 0x7b, 0x0a,
-  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, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20,
-  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
-  0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21, 0x3d, 0x20, 0x30,
-  0x29, 0x0a, 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, 0x20, 0x2b,
-  0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c, 0x6f, 0x67,
-  0x28, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x20, 0x2a,
-  0x20, 0x62, 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, 0x65, 0x6c, 0x73, 0x65, 0x0a, 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, 0x7d,
-  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, 0x5f, 0x76, 0x65, 0x63, 0x34, 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, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
-  0x79, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x69,
-  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
-  0x61, 0x6c, 0x65, 0x59, 0x2c, 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, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a, 0x75, 0x6c, 0x69,
-  0x61, 0x58, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a, 0x75,
-  0x6c, 0x69, 0x61, 0x59, 0x29, 0x20, 0x7b, 0x0a, 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, 0x20, 0x2a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65,
-  0x78, 0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e,
-  0x64, 0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b,
-  0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61,
-  0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x20,
-  0x28, 0x78, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
-  0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x28,
-  0x78, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78,
-  0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78,
-  0x6c, 0x2c, 0x20, 0x28, 0x78, 0x20, 0x2b, 0x20, 0x32, 0x29, 0x20, 0x2a,
+  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, 0x20, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x20, 0x79, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
   0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58,
-  0x20, 0x2b, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x28, 0x78, 0x20, 0x2b, 0x20,
-  0x33, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
-  0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62, 0x20,
-  0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x20, 0x28,
+  0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65,
+  0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 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, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a,
+  0x75, 0x6c, 0x69, 0x61, 0x58, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x59, 0x29, 0x20, 0x7b, 0x0a, 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, 0x69,
+  0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78,
+  0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x69, 0x6e, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64,
+  0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x20, 0x3d,
+  0x20, 0x78, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
+  0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x20, 0x3d, 0x20,
   0x79, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61,
-  0x6c, 0x65, 0x59, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x29, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x61, 0x20,
+  0x6c, 0x65, 0x59, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20,
+  0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x21, 0x3d, 0x20, 0x30, 0x20, 0x3f,
+  0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x58, 0x20, 0x3a, 0x20, 0x61, 0x3b,
+  0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x63, 0x62,
+  0x20, 0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x21, 0x3d, 0x20,
+  0x30, 0x20, 0x3f, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x59, 0x20, 0x3a,
+  0x20, 0x62, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20,
+  0x6e, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x61, 0x20,
+  0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x62,
+  0x20, 0x3d, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61,
+  0x62, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x61, 0x61,
+  0x20, 0x2b, 0x20, 0x62, 0x62, 0x20, 0x3e, 0x20, 0x31, 0x36, 0x29, 0x20,
+  0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 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, 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, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x7d, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20, 0x3e,
+  0x3d, 0x20, 0x6d, 0x61, 0x78, 0x20, 0x2d, 0x20, 0x31, 0x29, 0x20, 0x7b,
+  0x0a, 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, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65,
+  0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
+  0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21, 0x3d, 0x20,
+  0x30, 0x29, 0x0a, 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, 0x20,
+  0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c, 0x6f,
+  0x67, 0x28, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x20,
+  0x2a, 0x20, 0x62, 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, 0x65, 0x6c, 0x73, 0x65, 0x0a, 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,
+  0x7d, 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, 0x5f, 0x76, 0x65, 0x63, 0x34, 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, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x20, 0x79, 0x74, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70,
+  0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20,
+  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 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, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a, 0x75, 0x6c,
+  0x69, 0x61, 0x58, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6a,
+  0x75, 0x6c, 0x69, 0x61, 0x59, 0x29, 0x20, 0x7b, 0x0a, 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, 0x20, 0x2a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x69, 0x6e, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e, 0x64,
+  0x65, 0x78, 0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x69,
+  0x6e, 0x64, 0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68,
+  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20,
+  0x61, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29,
+  0x20, 0x28, 0x78, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x2c, 0x20,
+  0x28, 0x78, 0x20, 0x2b, 0x20, 0x31, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x69,
+  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20,
+  0x78, 0x6c, 0x2c, 0x20, 0x28, 0x78, 0x20, 0x2b, 0x20, 0x32, 0x29, 0x20,
+  0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65,
+  0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x2c, 0x20, 0x28, 0x78, 0x20, 0x2b,
+  0x20, 0x33, 0x29, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x58, 0x20, 0x2b, 0x20, 0x78, 0x6c, 0x29, 0x3b,
+  0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x62,
+  0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x20,
+  0x28, 0x79, 0x20, 0x2a, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63,
+  0x61, 0x6c, 0x65, 0x59, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x29, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x61,
+  0x20, 0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x3f, 0x20, 0x28,
+  0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x28, 0x6a, 0x75, 0x6c,
+  0x69, 0x61, 0x58, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x61, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x62, 0x20,
   0x3d, 0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x3f, 0x20, 0x28, 0x28,
   0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x28, 0x6a, 0x75, 0x6c, 0x69,
-  0x61, 0x58, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x62, 0x20, 0x3d,
-  0x20, 0x6a, 0x75, 0x6c, 0x69, 0x61, 0x20, 0x3f, 0x20, 0x28, 0x28, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x28, 0x6a, 0x75, 0x6c, 0x69, 0x61,
-  0x59, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x72, 0x65, 0x73, 0x61, 0x20,
-  0x3d, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x34, 0x20, 0x72, 0x65, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x62, 0x3b,
-  0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x34, 0x20, 0x63, 0x6f, 0x75,
-  0x6e, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x34, 0x29, 0x28,
-  0x30, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20,
-  0x6e, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x66,
-  0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x29, 0x20, 0x7b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65,
-  0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78, 0x29, 0x20, 0x7b,
+  0x61, 0x59, 0x29, 0x29, 0x20, 0x3a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20,
+  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x72, 0x65, 0x73, 0x61,
+  0x20, 0x3d, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x34, 0x20, 0x72, 0x65, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x62,
+  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x34, 0x20, 0x63, 0x6f,
+  0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x34, 0x29,
+  0x28, 0x30, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74,
+  0x20, 0x6e, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x69,
+  0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x29, 0x20, 0x7b,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c,
+  0x65, 0x20, 0x28, 0x6e, 0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78, 0x29, 0x20,
+  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x62, 0x20, 0x3d,
+  0x20, 0x61, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x34, 0x20, 0x63, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66,
+  0x6d, 0x61, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x20, 0x2a,
+  0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x34, 0x20, 0x63, 0x6d, 0x70,
+  0x20, 0x3d, 0x20, 0x69, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x28, 0x63, 0x6d,
+  0x70, 0x56, 0x61, 0x6c, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x34, 0x29, 0x28, 0x31, 0x36, 0x2e, 0x30, 0x66, 0x29, 0x29, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
+  0x66, 0x20, 0x28, 0x21, 0x61, 0x6e, 0x79, 0x28, 0x63, 0x6d, 0x70, 0x29,
+  0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20,
+  0x66, 0x6d, 0x61, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x2d, 0x66,
+  0x6d, 0x61, 0x28, 0x62, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x2d, 0x63, 0x61,
+  0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x32,
+  0x2c, 0x20, 0x61, 0x62, 0x2c, 0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
+  0x73, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x5f, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x34, 0x28, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28,
+  0x61, 0x29, 0x20, 0x26, 0x20, 0x63, 0x6d, 0x70, 0x29, 0x20, 0x7c, 0x20,
+  0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28, 0x72, 0x65, 0x73,
+  0x61, 0x29, 0x20, 0x26, 0x20, 0x7e, 0x63, 0x6d, 0x70, 0x29, 0x29, 0x3b,
   0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x61, 0x62, 0x20, 0x3d, 0x20,
-  0x61, 0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34,
-  0x20, 0x63, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x6d,
-  0x61, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x20, 0x2a, 0x20,
-  0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x34, 0x20, 0x63, 0x6d, 0x70, 0x20,
-  0x3d, 0x20, 0x69, 0x73, 0x6c, 0x65, 0x73, 0x73, 0x28, 0x63, 0x6d, 0x70,
-  0x56, 0x61, 0x6c, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34,
-  0x29, 0x28, 0x31, 0x36, 0x2e, 0x30, 0x66, 0x29, 0x29, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66,
-  0x20, 0x28, 0x21, 0x61, 0x6e, 0x79, 0x28, 0x63, 0x6d, 0x70, 0x29, 0x29,
-  0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x66,
-  0x6d, 0x61, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x2d, 0x66, 0x6d,
-  0x61, 0x28, 0x62, 0x2c, 0x20, 0x62, 0x2c, 0x20, 0x2d, 0x63, 0x61, 0x29,
+  0x72, 0x65, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x5f, 0x66, 0x6c,
+  0x6f, 0x61, 0x74, 0x34, 0x28, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74,
+  0x34, 0x28, 0x62, 0x29, 0x20, 0x26, 0x20, 0x63, 0x6d, 0x70, 0x29, 0x20,
+  0x7c, 0x20, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28, 0x72,
+  0x65, 0x73, 0x62, 0x29, 0x20, 0x26, 0x20, 0x7e, 0x63, 0x6d, 0x70, 0x29,
   0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x32, 0x2c,
-  0x20, 0x61, 0x62, 0x2c, 0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x73,
-  0x61, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x5f, 0x66, 0x6c, 0x6f, 0x61, 0x74,
-  0x34, 0x28, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28, 0x61,
-  0x29, 0x20, 0x26, 0x20, 0x63, 0x6d, 0x70, 0x29, 0x20, 0x7c, 0x20, 0x28,
-  0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28, 0x72, 0x65, 0x73, 0x61,
-  0x29, 0x20, 0x26, 0x20, 0x7e, 0x63, 0x6d, 0x70, 0x29, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
-  0x65, 0x73, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x73, 0x5f, 0x66, 0x6c, 0x6f,
-  0x61, 0x74, 0x34, 0x28, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34,
-  0x28, 0x62, 0x29, 0x20, 0x26, 0x20, 0x63, 0x6d, 0x70, 0x29, 0x20, 0x7c,
-  0x20, 0x28, 0x61, 0x73, 0x5f, 0x69, 0x6e, 0x74, 0x34, 0x28, 0x72, 0x65,
-  0x73, 0x62, 0x29, 0x20, 0x26, 0x20, 0x7e, 0x63, 0x6d, 0x70, 0x29, 0x29,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2b, 0x3d, 0x20, 0x63, 0x6d,
-  0x70, 0x20, 0x26, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x34, 0x29, 0x28, 0x31,
-  0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x6e, 0x20,
-  0x3c, 0x20, 0x6d, 0x61, 0x78, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x34, 0x20, 0x61, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20,
-  0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x6d, 0x70,
-  0x56, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x61, 0x2c,
-  0x20, 0x61, 0x2c, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
-  0x6e, 0x74, 0x34, 0x20, 0x63, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x69, 0x73,
-  0x6c, 0x65, 0x73, 0x73, 0x28, 0x63, 0x6d, 0x70, 0x56, 0x61, 0x6c, 0x2c,
-  0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x28, 0x31, 0x36,
-  0x2e, 0x30, 0x66, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21, 0x61,
-  0x6e, 0x79, 0x28, 0x63, 0x6d, 0x70, 0x29, 0x29, 0x20, 0x62, 0x72, 0x65,
-  0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x61,
-  0x2c, 0x20, 0x61, 0x2c, 0x20, 0x2d, 0x66, 0x6d, 0x61, 0x28, 0x62, 0x2c,
-  0x20, 0x62, 0x2c, 0x20, 0x2d, 0x63, 0x61, 0x29, 0x29, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62, 0x20,
-  0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x32, 0x2c, 0x20, 0x61, 0x62, 0x2c,
-  0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2b,
-  0x3d, 0x20, 0x63, 0x6d, 0x70, 0x20, 0x26, 0x20, 0x28, 0x69, 0x6e, 0x74,
-  0x34, 0x29, 0x28, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x7d, 0x0a, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69, 0x6e,
-  0x74, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20, 0x3c,
-  0x20, 0x34, 0x20, 0x26, 0x26, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x78, 0x20,
-  0x3c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x2b, 0x2b,
-  0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69,
-  0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21, 0x3d,
-  0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2b,
-  0x20, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x29, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5b, 0x69, 0x5d, 0x29,
-  0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x28, 0x6c,
-  0x6f, 0x67, 0x28, 0x66, 0x6d, 0x61, 0x28, 0x72, 0x65, 0x73, 0x61, 0x5b,
-  0x69, 0x5d, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x61, 0x5b, 0x69, 0x5d, 0x2c,
-  0x20, 0x72, 0x65, 0x73, 0x62, 0x5b, 0x69, 0x5d, 0x20, 0x2a, 0x20, 0x72,
-  0x65, 0x73, 0x62, 0x5b, 0x69, 0x5d, 0x29, 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, 0x65, 0x6c, 0x73,
-  0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2b, 0x20, 0x69, 0x5d,
-  0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20,
-  0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a
+  0x20, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x2b, 0x3d, 0x20, 0x63,
+  0x6d, 0x70, 0x20, 0x26, 0x20, 0x28, 0x69, 0x6e, 0x74, 0x34, 0x29, 0x28,
+  0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x77, 0x68, 0x69, 0x6c, 0x65, 0x20, 0x28, 0x6e,
+  0x20, 0x3c, 0x20, 0x6d, 0x61, 0x78, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x34, 0x20, 0x61, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a,
+  0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x20, 0x63, 0x6d,
+  0x70, 0x56, 0x61, 0x6c, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x61,
+  0x2c, 0x20, 0x61, 0x2c, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62, 0x29, 0x3b,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x69, 0x6e, 0x74, 0x34, 0x20, 0x63, 0x6d, 0x70, 0x20, 0x3d, 0x20, 0x69,
+  0x73, 0x6c, 0x65, 0x73, 0x73, 0x28, 0x63, 0x6d, 0x70, 0x56, 0x61, 0x6c,
+  0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x29, 0x28, 0x31,
+  0x36, 0x2e, 0x30, 0x66, 0x29, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x21,
+  0x61, 0x6e, 0x79, 0x28, 0x63, 0x6d, 0x70, 0x29, 0x29, 0x20, 0x62, 0x72,
+  0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28,
+  0x61, 0x2c, 0x20, 0x61, 0x2c, 0x20, 0x2d, 0x66, 0x6d, 0x61, 0x28, 0x62,
+  0x2c, 0x20, 0x62, 0x2c, 0x20, 0x2d, 0x63, 0x61, 0x29, 0x29, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x62,
+  0x20, 0x3d, 0x20, 0x66, 0x6d, 0x61, 0x28, 0x32, 0x2c, 0x20, 0x61, 0x62,
+  0x2c, 0x20, 0x63, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20,
+  0x2b, 0x3d, 0x20, 0x63, 0x6d, 0x70, 0x20, 0x26, 0x20, 0x28, 0x69, 0x6e,
+  0x74, 0x34, 0x29, 0x28, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x2b, 0x2b, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x28, 0x69,
+  0x6e, 0x74, 0x20, 0x69, 0x20, 0x3d, 0x20, 0x30, 0x3b, 0x20, 0x69, 0x20,
+  0x3c, 0x20, 0x34, 0x20, 0x26, 0x26, 0x20, 0x69, 0x20, 0x2b, 0x20, 0x78,
+  0x20, 0x3c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x20, 0x69, 0x2b,
+  0x2b, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x69, 0x66, 0x20, 0x28, 0x73, 0x6d, 0x6f, 0x6f, 0x74, 0x68, 0x20, 0x21,
+  0x3d, 0x20, 0x30, 0x29, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20,
+  0x2b, 0x20, 0x69, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x29, 0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5b, 0x69, 0x5d,
+  0x29, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20, 0x6c, 0x6f, 0x67, 0x28,
+  0x6c, 0x6f, 0x67, 0x28, 0x66, 0x6d, 0x61, 0x28, 0x72, 0x65, 0x73, 0x61,
+  0x5b, 0x69, 0x5d, 0x2c, 0x20, 0x72, 0x65, 0x73, 0x61, 0x5b, 0x69, 0x5d,
+  0x2c, 0x20, 0x72, 0x65, 0x73, 0x62, 0x5b, 0x69, 0x5d, 0x20, 0x2a, 0x20,
+  0x72, 0x65, 0x73, 0x62, 0x5b, 0x69, 0x5d, 0x29, 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, 0x65, 0x6c,
+  0x73, 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x41, 0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2b, 0x20, 0x69,
+  0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29,
+  0x20, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5b, 0x69, 0x5d, 0x29, 0x3b, 0x0a,
+  0x20, 0x20, 0x20, 0x7d, 0x0a, 0x7d, 0x0a, 0x0a
 };
-unsigned int float_cl_len = 2563;
+unsigned int float_cl_len = 2564;

+ 1 - 2
libmandel/src/opencl/makefile

@@ -2,8 +2,7 @@
 HEADERS := $(patsubst %.cl,%.h,$(wildcard *.cl))
 
 
-all:
-	$(HEADERS)
+all: $(HEADERS)
 
 %.h: %.cl
 	xxd -i $< > $@