Nicolas Winkler 5 years ago
parent
commit
9838a33e60

+ 1 - 1
Almond.cpp

@@ -119,7 +119,7 @@ void Almond::on_exportImage_clicked()
         mi.bWidth = dialog.getWidth();
         mi.bWidth = dialog.getWidth();
         mi.bHeight = dialog.getHeight();
         mi.bHeight = dialog.getHeight();
         mi.view.adjustAspectRatio(mi.bWidth, mi.bHeight);
         mi.view.adjustAspectRatio(mi.bWidth, mi.bHeight);
-        mnd::Generator& g = mandelContext.getDefaultGenerator();
+        mnd::Generator& g = currentGenerator ? *currentGenerator : mandelContext.getDefaultGenerator();
         auto fmap = Bitmap<float>(mi.bWidth, mi.bHeight);
         auto fmap = Bitmap<float>(mi.bWidth, mi.bHeight);
         g.generate(mi, fmap.pixels.get());
         g.generate(mi, fmap.pixels.get());
         auto bitmap = fmap.map<RGBColor>([&mi, this] (float i) {
         auto bitmap = fmap.map<RGBColor>([&mi, this] (float i) {

+ 5 - 3
Gradient.cpp

@@ -96,7 +96,7 @@ Gradient Gradient::readXml(const QString& xml)
 
 
 RGBColor Gradient::get(float x) const
 RGBColor Gradient::get(float x) const
 {
 {
-    if (colors.empty())
+    if (colors.empty() || ::isnan(x) || ::isinf(x))
         return RGBColor();
         return RGBColor();
     /*const auto [left, right, lerp] = getNeighbors(x);
     /*const auto [left, right, lerp] = getNeighbors(x);
     RGBColor lerped = lerpColors(left, right, lerp);
     RGBColor lerped = lerpColors(left, right, lerp);
@@ -107,6 +107,8 @@ RGBColor Gradient::get(float x) const
     if (x > this->max) {
     if (x > this->max) {
         if (repeat)
         if (repeat)
             x = ::fmodf(x, this->max);
             x = ::fmodf(x, this->max);
+        else
+            x = this->max;
     }
     }
     float pos = x * colors.size() / max;
     float pos = x * colors.size() / max;
     if (pos < 0) {
     if (pos < 0) {
@@ -121,10 +123,10 @@ RGBColor Gradient::get(float x) const
     float lerp = pos - left;
     float lerp = pos - left;
 
 
     if (lerp < 1e-5f) {
     if (lerp < 1e-5f) {
-        return colors.at(left);
+        return colors[left];
     }
     }
     else {
     else {
-        return lerpColors(colors.at(left), colors.at(right), lerp);
+        return lerpColors(colors[left], colors[right], lerp);
     }
     }
 }
 }
 
 

+ 18 - 6
MandelWidget.cpp

@@ -6,6 +6,8 @@ using namespace mnd;
 
 
 #include <QPainter>
 #include <QPainter>
 
 
+#include <cstdio>
+
 
 
 Texture::Texture(const Bitmap<RGBColor>& bitmap, GLint param)
 Texture::Texture(const Bitmap<RGBColor>& bitmap, GLint param)
 {
 {
@@ -226,11 +228,21 @@ void Job::run(void)
     mi->bWidth = mi->bHeight = MandelView::chunkSize;
     mi->bWidth = mi->bHeight = MandelView::chunkSize;
     mi->maxIter = owner.getMaxIterations();
     mi->maxIter = owner.getMaxIterations();
     mi->smooth = owner.getSmoothColoring();
     mi->smooth = owner.getSmoothColoring();
-    generator->generate(*mi, f.pixels.get());
-    auto* rgb = new Bitmap<RGBColor>(f.map<RGBColor>([&mi, this](float i) {
-        return i >= mi->maxIter ? RGBColor{ 0, 0, 0 } : gradient.get(i);
-    }));
-    emit done(level, i, j, calcState, rgb);
+    try {
+        generator->generate(*mi, f.pixels.get());
+        auto* rgb = new Bitmap<RGBColor>(f.map<RGBColor>([&mi, this](float i) {
+            return i >= mi->maxIter ? RGBColor{ 0, 0, 0 } : gradient.get(i);
+        }));
+        emit done(level, i, j, calcState, rgb);
+    }
+    catch(std::exception& ex) {
+        printf("wat: %s?!\n", ex.what()); fflush(stdout);
+        exit(1);
+    }
+    catch(...) {
+        printf("wat?!\n"); fflush(stdout);
+        exit(1);
+    }
 }
 }
 
 
 
 
@@ -531,7 +543,7 @@ void MandelView::paint(const mnd::MandelViewport& mvp)
                     t = under;
                     t = under;
                 }
                 }
                 else {
                 else {
-                    auto above = searchAbove(level, i, j, 2);
+                    auto above = searchAbove(level, i, j, 3);
                     if (above) {
                     if (above) {
                         t = above;
                         t = above;
                     }
                     }

+ 13 - 0
libmandel/include/ClGenerators.h

@@ -20,6 +20,7 @@ namespace mnd
     class ClGeneratorDoubleDouble;
     class ClGeneratorDoubleDouble;
     class ClGeneratorQuadDouble;
     class ClGeneratorQuadDouble;
     class ClGenerator128;
     class ClGenerator128;
+    class ClGenerator64;
 }
 }
 
 
 
 
@@ -112,6 +113,18 @@ protected:
     virtual std::string getKernelCode(bool smooth) const;
     virtual std::string getKernelCode(bool smooth) const;
 };
 };
 
 
+
+class mnd::ClGenerator64 : public ClGenerator
+{
+public:
+    ClGenerator64(cl::Device device);
+    virtual ~ClGenerator64(void) = default;
+
+    virtual void generate(const MandelInfo& info, float* data);
+protected:
+    virtual std::string getKernelCode(bool smooth) const;
+};
+
 #endif // WITH_OPENCL
 #endif // WITH_OPENCL
 
 
 #endif // MANDEL_CLGENERATORS_H
 #endif // MANDEL_CLGENERATORS_H

+ 14 - 0
libmandel/include/Fixed.h

@@ -27,11 +27,21 @@ struct Fixed512
             240, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
             240, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
             boost::multiprecision::et_off>;
             boost::multiprecision::et_off>;
 
 
+    using Float512 = boost::multiprecision::number<
+        boost::multiprecision::backends::cpp_bin_float<
+            496, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
+            boost::multiprecision::et_off>;
+
     inline Fixed512(const Float256& val)
     inline Fixed512(const Float256& val)
     {
     {
         body = Once{ val * boost::multiprecision::pow(Float256{ 2 }, 512 - 32) };
         body = Once{ val * boost::multiprecision::pow(Float256{ 2 }, 512 - 32) };
     }
     }
 
 
+    inline Fixed512(const Float512& val)
+    {
+        body = Once{ val * boost::multiprecision::pow(Float512{ 2 }, 512 - 32) };
+    }
+
     inline Fixed512(double val)
     inline Fixed512(double val)
     {
     {
         body = Once{ boost::multiprecision::pow(Float256{ 2 }, 512 - 32) * val };
         body = Once{ boost::multiprecision::pow(Float256{ 2 }, 512 - 32) * val };
@@ -41,6 +51,10 @@ struct Fixed512
         return boost::multiprecision::pow(Float256{ 0.5 }, 512 - 32) * Float256{ body };
         return boost::multiprecision::pow(Float256{ 0.5 }, 512 - 32) * Float256{ body };
     }
     }
 
 
+    inline operator Float512(void) const {
+        return boost::multiprecision::pow(Float512{ 0.5 }, 512 - 32) * Float512{ body };
+    }
+
     inline Fixed512& operator += (const Fixed512& other) {
     inline Fixed512& operator += (const Fixed512& other) {
         body += other.body;
         body += other.body;
         return *this;
         return *this;

+ 13 - 2
libmandel/include/Types.h

@@ -52,8 +52,19 @@ namespace mnd
     inline Float256 log2(const Float256& x) { return boost::multiprecision::log2(x); }
     inline Float256 log2(const Float256& x) { return boost::multiprecision::log2(x); }
     inline Float256 pow(const Float256& x, const Float256& y) { return boost::multiprecision::pow(x, y); }
     inline Float256 pow(const Float256& x, const Float256& y) { return boost::multiprecision::pow(x, y); }
 
 
-    using Real = Float256;
-    using Integer = boost::multiprecision::int256_t;
+    using Float512 = boost::multiprecision::number<
+        boost::multiprecision::backends::cpp_bin_float<
+            496, boost::multiprecision::backends::digit_base_2, void, boost::int16_t, -16382, 16383>,
+            boost::multiprecision::et_off>;
+
+    inline Float512 abs(const Float512& x) { return boost::multiprecision::abs(x); }
+    inline Float512 floor(const Float512& x) { return boost::multiprecision::floor(x); }
+    inline Float512 log(const Float512& x) { return boost::multiprecision::log(x); }
+    inline Float512 log2(const Float512& x) { return boost::multiprecision::log2(x); }
+    inline Float512 pow(const Float512& x, const Float512& y) { return boost::multiprecision::pow(x, y); }
+
+    using Real = Float512;
+    using Integer = boost::multiprecision::int512_t;
 #else
 #else
     using Real = double;
     using Real = double;
     using Integer = int64_t;
     using Integer = int64_t;

+ 199 - 17
libmandel/src/ClGenerators.cpp

@@ -1,6 +1,8 @@
 #include "ClGenerators.h"
 #include "ClGenerators.h"
 #include "doubledouble.h"
 #include "doubledouble.h"
 #include "doublefloat.h"
 #include "doublefloat.h"
+#include "opencl/fixed512.h"
+#include "opencl/fixed64.h"
 
 
 #ifdef WITH_OPENCL
 #ifdef WITH_OPENCL
 
 
@@ -18,6 +20,7 @@ using mnd::ClGeneratorDouble;
 using mnd::ClGeneratorDoubleDouble;
 using mnd::ClGeneratorDoubleDouble;
 using mnd::ClGeneratorQuadDouble;
 using mnd::ClGeneratorQuadDouble;
 using mnd::ClGenerator128;
 using mnd::ClGenerator128;
+using mnd::ClGenerator64;
 
 
 Platform getPlatform() {
 Platform getPlatform() {
     /* Returns the first platform found. */
     /* Returns the first platform found. */
@@ -189,26 +192,132 @@ ClGeneratorDoubleFloat::ClGeneratorDoubleFloat(cl::Device device) :
 }
 }
 
 
 
 
+std::pair<float, float> twoSum(float a, float b) {
+    float s = a + b;
+    float v = s - a;
+    float r = (a - (s - v)) + (b - v);
+    return { s, r };
+}
+
+std::pair<float, float> split(float a) {
+    float c = (4096 + 1) * a;
+    float abig = c - a;
+    float ahi = c - abig;
+    float alo = a - ahi;
+    return { ahi, alo };
+}
+
+std::pair<float, float> twoProd(float a, float b) {
+    float x = a * b;
+    auto aex = split(a);
+    auto bex = split(b);
+    float errx = x - (aex.first * bex.first);
+    float erry = errx - (aex.second * bex.first);
+    float errz = erry - (aex.first * bex.second);
+    float y = (aex.second * bex.second) - errz;
+    return { x, y };
+}
+
+std::pair<float, float> add(std::pair<float, float> a, std::pair<float, float> b) {
+    float r = a.first + b.first;
+    float s;
+    if (fabs(a.first) >= fabs(b.first)) {
+        s = (((a.first - r) + b.first) + b.second) + a.second;
+    }
+    else {
+        s = (((b.first - r) + a.first) + a.second) + b.second;
+    }
+    return twoSum(r, s);
+}
+
+std::pair<float, float> mul(std::pair<float, float> a, std::pair<float, float> b) {
+    auto t = twoProd(a.first, b.first);
+    float t3 = ((a.first * b.second) + (a.second * b.first)) + t.second;
+    return twoSum(t.first, t.second);
+}
+
+std::pair<float, float> mulFloat(std::pair<float, float> a, float b) {
+    std::pair<float, float> t = twoProd(a.first, b);
+    float t3 = (a.second * b) + t.second;
+    return twoSum(t.first, t.second);
+}
+
+
 void ClGeneratorDoubleFloat::generate(const mnd::MandelInfo& info, float* data)
 void ClGeneratorDoubleFloat::generate(const mnd::MandelInfo& info, float* data)
 {
 {
     ::size_t bufferSize = info.bWidth * info.bHeight * sizeof(float);
     ::size_t bufferSize = info.bWidth * info.bHeight * sizeof(float);
 
 
+    auto add12 = [](float a, float b) {
+        float s = a + b;
+        float v = s - a;
+        float r = (a - (s - v)) + (b - v);
+        return std::pair{ s, r };
+    };
+
     auto splitDouble = [] (double x) {
     auto splitDouble = [] (double x) {
+        /*uint64_t xl = *((uint64_t*)&x);
+        uint64_t mantissa = xl & 0x000FFFFFFFFFFFFFULL;
+        uint64_t exp = (xl & 0x7FF0000000000000ULL) >> 53;
+        bool sign = (xl & 0x1000000000000000ULL) != 0;
+
+        uint32_t floathi = exp << 23;*/
+
         float hi = float(x);
         float hi = float(x);
         float lo = float(x - double(hi));
         float lo = float(x - double(hi));
-        return std::pair{ hi, lo };
+        if (abs(lo) >= 1.0e-10f) {
+            //printf("hi: %.10ef, lo: %.10ef\n", hi, lo);
+            //fflush(stdout);
+        }
+        return std::pair{ hi, 0.0f };
     };
     };
 
 
     Buffer buffer_A(context, CL_MEM_WRITE_ONLY, bufferSize);
     Buffer buffer_A(context, CL_MEM_WRITE_ONLY, bufferSize);
-    double pixelScaleX = double(info.view.width / info.bWidth);
-    double pixelScaleY = double(info.view.height / info.bHeight);
+    double pixelScX = double(info.view.width / info.bWidth);
+    double pixelScY = double(info.view.height / info.bHeight);
 
 
     auto[x1, x2] = splitDouble(double(info.view.x));
     auto[x1, x2] = splitDouble(double(info.view.x));
     auto[y1, y2] = splitDouble(double(info.view.y));
     auto[y1, y2] = splitDouble(double(info.view.y));
-    auto[w1, w2] = splitDouble(pixelScaleX);
-    auto[h1, h2] = splitDouble(pixelScaleY);
-
-
+    auto[w1, w2] = splitDouble(pixelScX);
+    auto[h1, h2] = splitDouble(pixelScY);
+
+    for (int px = 0; px < info.bWidth; px++) {
+        for (int py = 0; py < info.bHeight; py++) {
+            std::pair<float, float> xl = { x1, x2 };
+            std::pair<float, float> yt = { y1, y2 };
+            std::pair<float, float> pixelScaleX = { w1, w2 };
+            std::pair<float, float> pixelScaleY = { h1, h2 };
+
+            std::pair<float, float> a = add(mulFloat(pixelScaleX, (float) px), xl); // pixelScaleX * px + xl
+            std::pair<float, float> b = add(mulFloat(pixelScaleY, (float) py), yt); // pixelScaleY * py + yt
+            std::pair<float, float> ca = a;
+            std::pair<float, float> cb = b;
+
+            int n = 0;
+            while (n < info.maxIter - 1) {
+                std::pair<float, float> aa = mul(a, a);
+                std::pair<float, float> bb = mul(b, b);
+                std::pair<float, float> ab = mul(a, b);
+                if (aa.first + bb.first > 16) break;
+                std::pair<float, float> minusbb = { -bb.first, -bb.second };
+                a = add(add(aa, minusbb), ca);
+                b = add(add(ab, ab), cb);
+                n++;
+            }
+
+            // N + 1 - log (log  |Z(N)|) / log 2
+            if (n >= info.maxIter - 1)
+                data[px + py * info.bWidth] = info.maxIter;
+            else {
+                if (info.smooth)
+                    data[px + py * info.bWidth] = ((float) n) + 1 - log(log(a.first * a.first + b.first * b.first ) / 2) / log(2.0f);
+                else
+                    data[px + py * info.bWidth] = ((float)n);
+            }
+        }
+    }
+    return;
+   
+    
     Kernel iterate = Kernel(program, "iterate");
     Kernel iterate = Kernel(program, "iterate");
     iterate.setArg(0, buffer_A);
     iterate.setArg(0, buffer_A);
     iterate.setArg(1, int(info.bWidth));
     iterate.setArg(1, int(info.bWidth));
@@ -415,6 +524,7 @@ void ClGeneratorQuadDouble::generate(const mnd::MandelInfo& info, float* data)
 
 
     cl_int result = queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
     cl_int result = queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
+
 }
 }
 
 
 
 
@@ -451,33 +561,105 @@ void ClGenerator128::generate(const mnd::MandelInfo& info, float* data)
     float pixelScaleX = float(info.view.width / info.bWidth);
     float pixelScaleX = float(info.view.width / info.bWidth);
     float pixelScaleY = float(info.view.height / info.bHeight);
     float pixelScaleY = float(info.view.height / info.bHeight);
 
 
+    using ull = unsigned long long;
+    ull x1 = ull(double(info.view.x) * 0x100000000ULL);
+    ull x2 = 0;
+    ull y1 = ull(double(info.view.y) * 0x100000000ULL);
+    ull y2 = 0;
+    ull w1 = ull(double(pixelScaleX) * 0x100000000ULL);
+    ull w2 = 0;
+    ull h1 = ull(double(pixelScaleY) * 0x100000000ULL);
+    ull h2 = 0;
+
     Kernel iterate = Kernel(program, "iterate");
     Kernel iterate = Kernel(program, "iterate");
     iterate.setArg(0, buffer_A);
     iterate.setArg(0, buffer_A);
     iterate.setArg(1, int(info.bWidth));
     iterate.setArg(1, int(info.bWidth));
-    iterate.setArg(2, double(info.view.x));
-    iterate.setArg(3, double(info.view.y));
-    iterate.setArg(4, double(pixelScaleX));
-    iterate.setArg(5, double(pixelScaleY));
-    iterate.setArg(6, int(info.maxIter));
+    iterate.setArg(2, ull(x1));
+    iterate.setArg(3, ull(x2));
+    iterate.setArg(4, ull(y1));
+    iterate.setArg(5, ull(y2));
+    iterate.setArg(6, ull(w1));
+    iterate.setArg(7, ull(w2));
+    iterate.setArg(8, ull(h1));
+    iterate.setArg(9, ull(h2));
+    iterate.setArg(10, int(info.maxIter));
+    iterate.setArg(11, int(info.smooth ? 1 : 0));
 
 
     queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
     queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
 }
 }
 
 
-#include <string>
-#include <fstream>
-#include <streambuf>
 
 
 std::string ClGenerator128::getKernelCode(bool smooth) const
 std::string ClGenerator128::getKernelCode(bool smooth) const
 {
 {
-    //fprintf(stderr, "starting file read\n");
+    /*//fprintf(stderr, "starting file read\n");
     std::ifstream t("mandel128.cl");
     std::ifstream t("mandel128.cl");
     std::string str((std::istreambuf_iterator<char>(t)),
     std::string str((std::istreambuf_iterator<char>(t)),
         std::istreambuf_iterator<char>());
         std::istreambuf_iterator<char>());
     //fprintf(stderr, "%s\n", str);
     //fprintf(stderr, "%s\n", str);
-    return str;
+    return str;*/
+    return (char*) fixed512_cl;
+}
+
+
+ClGenerator64::ClGenerator64(cl::Device device) :
+    ClGenerator{ device }
+{
+    context = Context{ device };
+    Program::Sources sources;
+
+    std::string kcode = this->getKernelCode(false);
+
+    sources.push_back({ kcode.c_str(), kcode.length() });
+
+    program = Program{ context, sources };
+    if (program.build({ device }) != CL_SUCCESS) {
+        throw std::string(program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device));
+    }
+
+    queue = CommandQueue(context, device);
 }
 }
 
 
 
 
+void ClGenerator64::generate(const mnd::MandelInfo& info, float* data)
+{
+    ::size_t bufferSize = info.bWidth * info.bHeight * sizeof(float);
+
+    Buffer buffer_A(context, CL_MEM_WRITE_ONLY, bufferSize);
+    float pixelScaleX = float(info.view.width / info.bWidth);
+    float pixelScaleY = float(info.view.height / info.bHeight);
+
+    using ull = unsigned long long;
+    ull x = ull(double(info.view.x) * 0x1000000000000ULL);
+    ull y = ull(double(info.view.y) * 0x1000000000000ULL);
+    ull w = ull(double(pixelScaleX) * 0x1000000000000ULL);
+    ull h = ull(double(pixelScaleY) * 0x1000000000000ULL);
+
+    Kernel iterate = Kernel(program, "iterate");
+    iterate.setArg(0, buffer_A);
+    iterate.setArg(1, int(info.bWidth));
+    iterate.setArg(2, ull(x));
+    iterate.setArg(3, ull(y));
+    iterate.setArg(4, ull(w));
+    iterate.setArg(5, ull(h));
+    iterate.setArg(6, int(info.maxIter));
+    iterate.setArg(7, int(info.smooth ? 1 : 0));
+
+    queue.enqueueNDRangeKernel(iterate, 0, NDRange(info.bWidth * info.bHeight));
+    queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, bufferSize, data);
+}
+
+
+std::string ClGenerator64::getKernelCode(bool smooth) const
+{
+    /*//fprintf(stderr, "starting file read\n");
+    std::ifstream t("mandel128.cl");
+    std::string str((std::istreambuf_iterator<char>(t)),
+    std::istreambuf_iterator<char>());
+    //fprintf(stderr, "%s\n", str);
+    return str;*/
+    return (char*) fixed64_cl;
+}
+
 #endif // WITH_OPENCL
 #endif // WITH_OPENCL
 
 

+ 4 - 2
libmandel/src/Mandel.cpp

@@ -162,6 +162,7 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
     auto* doubleDoubleGen = getCpuGenerator(GeneratorType::DOUBLE_DOUBLE);
     auto* doubleDoubleGen = getCpuGenerator(GeneratorType::DOUBLE_DOUBLE);
     auto* quadDoubleGen = getCpuGenerator(GeneratorType::QUAD_DOUBLE);
     auto* quadDoubleGen = getCpuGenerator(GeneratorType::QUAD_DOUBLE);
     auto* f256Gen = getCpuGenerator(GeneratorType::FLOAT256);
     auto* f256Gen = getCpuGenerator(GeneratorType::FLOAT256);
+    auto* fix512 = getCpuGenerator(GeneratorType::FIXED512);
 
 
     if (cpuInfo.hasAvx()) {
     if (cpuInfo.hasAvx()) {
         floatGen = getCpuGenerator(GeneratorType::FLOAT_AVX);
         floatGen = getCpuGenerator(GeneratorType::FLOAT_AVX);
@@ -200,7 +201,7 @@ std::unique_ptr<mnd::AdaptiveGenerator> MandelContext::createAdaptiveGenerator(v
     ag->addGenerator(Precision::DOUBLE_DOUBLE, *doubleDoubleGen);
     ag->addGenerator(Precision::DOUBLE_DOUBLE, *doubleDoubleGen);
     ag->addGenerator(Precision::QUAD_DOUBLE, *quadDoubleGen);
     ag->addGenerator(Precision::QUAD_DOUBLE, *quadDoubleGen);
     ag->addGenerator(Precision::FLOAT256, *f256Gen);
     ag->addGenerator(Precision::FLOAT256, *f256Gen);
-    ag->addGenerator(Precision::INF_PREC, *f256Gen);
+    ag->addGenerator(Precision::INF_PREC, *fix512);
 
 
     return ag;
     return ag;
 }
 }
@@ -244,7 +245,8 @@ std::vector<MandelDevice> MandelContext::createDevices(void)
             //printf("    using opencl device: %s\n", md.name.c_str());
             //printf("    using opencl device: %s\n", md.name.c_str());
             try {
             try {
                 md.generators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(device) });
                 md.generators.insert({ GeneratorType::FLOAT, std::make_unique<ClGeneratorFloat>(device) });
-                md.generators.insert({ GeneratorType::DOUBLE_FLOAT, std::make_unique<ClGeneratorDoubleFloat>(device) });
+                md.generators.insert({ GeneratorType::FIXED512, std::make_unique<ClGenerator64>(device) });
+                //md.generators.insert({ GeneratorType::DOUBLE_FLOAT, std::make_unique<ClGeneratorDoubleFloat>(device) });
             }
             }
             catch (const std::string& err) {
             catch (const std::string& err) {
                 printf("err: %s", err.c_str());
                 printf("err: %s", err.c_str());

+ 3 - 5
libmandel/src/doublefloat.cl

@@ -10,7 +10,7 @@ float2 twoSum(float a, float b) {
 }
 }
 
 
 float2 split(float a) {
 float2 split(float a) {
-    float c = (65536 + 1) * a;
+    float c = (4096 + 1) * a;
     float abig = c - a;
     float abig = c - a;
     float ahi = c - abig;
     float ahi = c - abig;
     float alo = a - ahi;
     float alo = a - ahi;
@@ -52,7 +52,7 @@ float2 mulFloat(float2 a, float b) {
     return twoSum(t.s0, t.s1);
     return twoSum(t.s0, t.s1);
 }
 }
 
 
-__kernel void iterate(__global float* A, const int width,
+__kernel void iterate(__global __write_only float* A, const int width,
                       float x1, float x2, float y1, float y2,
                       float x1, float x2, float y1, float y2,
                       float pw1, float pw2, float ph1, float ph2, int max, int smooth) {
                       float pw1, float pw2, float ph1, float ph2, int max, int smooth) {
     int index = get_global_id(0);
     int index = get_global_id(0);
@@ -74,7 +74,7 @@ __kernel void iterate(__global float* A, const int width,
         float2 aa = mul(a, a);
         float2 aa = mul(a, a);
         float2 bb = mul(b, b);
         float2 bb = mul(b, b);
         float2 ab = mul(a, b);
         float2 ab = mul(a, b);
-        if (aa.s0 + aa.s1 + bb.s0 + bb.s1 > 16) break;
+        if (aa.s0 + bb.s0 > 16) break;
         float2 minusbb = (float2)(-bb.s0, -bb.s1);
         float2 minusbb = (float2)(-bb.s0, -bb.s1);
         a = add(add(aa, minusbb), ca);
         a = add(add(aa, minusbb), ca);
         b = add(add(ab, ab), cb);
         b = add(add(ab, ab), cb);
@@ -90,6 +90,4 @@ __kernel void iterate(__global float* A, const int width,
         else
         else
             A[index] = ((float)n);
             A[index] = ((float)n);
     }
     }
-    //               A[index] = ((float)n) + 1 - (a * a + b * b - 16) / (256 - 16);
-    //           A[get_global_id(0)] = 5;
 }
 }

+ 203 - 207
libmandel/src/doublefloat.h

@@ -8,231 +8,227 @@ unsigned char doublefloat_cl[] = {
   0x2d, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61,
   0x2d, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x6f, 0x70, 0x65, 0x72, 0x61,
   0x74, 0x6f, 0x72, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x67, 0x72, 0x61, 0x70,
   0x74, 0x6f, 0x72, 0x73, 0x20, 0x6f, 0x6e, 0x20, 0x67, 0x72, 0x61, 0x70,
   0x68, 0x69, 0x63, 0x73, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72,
   0x68, 0x69, 0x63, 0x73, 0x20, 0x68, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72,
-  0x65, 0x2e, 0x0a, 0x2f, 0x2f, 0x20, 0x52, 0x65, 0x61, 0x6c, 0x20, 0x4e,
-  0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x43,
-  0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x73, 0x20, 0x37, 0x2c, 0x20,
-  0x4a, 0x75, 0x6c, 0x20, 0x32, 0x30, 0x30, 0x36, 0x2c, 0x20, 0x4e, 0x61,
-  0x6e, 0x63, 0x79, 0x2c, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65, 0x2e,
-  0x20, 0x70, 0x70, 0x2e, 0x32, 0x33, 0x2d, 0x33, 0x32, 0x2e, 0x20, 0x66,
-  0x66, 0x68, 0x61, 0x6c, 0x2d, 0x30, 0x30, 0x30, 0x32, 0x31, 0x34, 0x34,
-  0x33, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f,
-  0x2f, 0x68, 0x61, 0x6c, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69, 0x76, 0x65,
-  0x73, 0x2d, 0x6f, 0x75, 0x76, 0x65, 0x72, 0x74, 0x65, 0x73, 0x2e, 0x66,
-  0x72, 0x2f, 0x68, 0x61, 0x6c, 0x2d, 0x30, 0x30, 0x30, 0x32, 0x31, 0x34,
-  0x34, 0x33, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x0a,
-  0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x77, 0x6f, 0x53,
-  0x75, 0x6d, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x2c, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, 0x20, 0x3d,
-  0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x76, 0x20, 0x3d, 0x20, 0x73, 0x20,
-  0x2d, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f,
-  0x61, 0x74, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x20, 0x2d, 0x20,
-  0x28, 0x73, 0x20, 0x2d, 0x20, 0x76, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x28,
-  0x62, 0x20, 0x2d, 0x20, 0x76, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x32, 0x29, 0x28, 0x73, 0x2c, 0x20, 0x72, 0x29, 0x3b, 0x0a, 0x7d,
-  0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x73, 0x70, 0x6c,
-  0x69, 0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x29, 0x20,
-  0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
-  0x63, 0x20, 0x3d, 0x20, 0x28, 0x36, 0x35, 0x35, 0x33, 0x36, 0x20, 0x2b,
-  0x20, 0x31, 0x29, 0x20, 0x2a, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x65, 0x2e, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x52, 0x65, 0x61, 0x6c, 0x20,
+  0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x73, 0x20, 0x61, 0x6e, 0x64, 0x20,
+  0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x72, 0x73, 0x20, 0x37, 0x2c,
+  0x20, 0x4a, 0x75, 0x6c, 0x20, 0x32, 0x30, 0x30, 0x36, 0x2c, 0x20, 0x4e,
+  0x61, 0x6e, 0x63, 0x79, 0x2c, 0x20, 0x46, 0x72, 0x61, 0x6e, 0x63, 0x65,
+  0x2e, 0x20, 0x70, 0x70, 0x2e, 0x32, 0x33, 0x2d, 0x33, 0x32, 0x2e, 0x20,
+  0x66, 0x66, 0x68, 0x61, 0x6c, 0x2d, 0x30, 0x30, 0x30, 0x32, 0x31, 0x34,
+  0x34, 0x33, 0x0d, 0x0a, 0x2f, 0x2f, 0x20, 0x68, 0x74, 0x74, 0x70, 0x73,
+  0x3a, 0x2f, 0x2f, 0x68, 0x61, 0x6c, 0x2e, 0x61, 0x72, 0x63, 0x68, 0x69,
+  0x76, 0x65, 0x73, 0x2d, 0x6f, 0x75, 0x76, 0x65, 0x72, 0x74, 0x65, 0x73,
+  0x2e, 0x66, 0x72, 0x2f, 0x68, 0x61, 0x6c, 0x2d, 0x30, 0x30, 0x30, 0x32,
+  0x31, 0x34, 0x34, 0x33, 0x2f, 0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e,
+  0x74, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
+  0x74, 0x77, 0x6f, 0x53, 0x75, 0x6d, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x20, 0x61, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x29,
+  0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
+  0x76, 0x20, 0x3d, 0x20, 0x73, 0x20, 0x2d, 0x20, 0x61, 0x3b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x72, 0x20,
+  0x3d, 0x20, 0x28, 0x61, 0x20, 0x2d, 0x20, 0x28, 0x73, 0x20, 0x2d, 0x20,
+  0x76, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x62, 0x20, 0x2d, 0x20, 0x76,
+  0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75,
+  0x72, 0x6e, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28,
+  0x73, 0x2c, 0x20, 0x72, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d,
+  0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x73, 0x70, 0x6c, 0x69,
+  0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x29, 0x20, 0x7b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
+  0x63, 0x20, 0x3d, 0x20, 0x28, 0x34, 0x30, 0x39, 0x36, 0x20, 0x2b, 0x20,
+  0x31, 0x29, 0x20, 0x2a, 0x20, 0x61, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
   0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x62, 0x69, 0x67, 0x20,
   0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x62, 0x69, 0x67, 0x20,
-  0x3d, 0x20, 0x63, 0x20, 0x2d, 0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x68, 0x69, 0x20, 0x3d,
-  0x20, 0x63, 0x20, 0x2d, 0x20, 0x61, 0x62, 0x69, 0x67, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x6c, 0x6f,
-  0x20, 0x3d, 0x20, 0x61, 0x20, 0x2d, 0x20, 0x61, 0x68, 0x69, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x61, 0x68, 0x69, 0x2c,
-  0x20, 0x61, 0x6c, 0x6f, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x77, 0x6f, 0x50, 0x72, 0x6f, 0x64,
-  0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x2c, 0x20, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x61,
-  0x20, 0x2a, 0x20, 0x62, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x73,
-  0x70, 0x6c, 0x69, 0x74, 0x28, 0x61, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x62, 0x65, 0x78, 0x20,
-  0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74, 0x28, 0x62, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x72,
-  0x72, 0x78, 0x20, 0x3d, 0x20, 0x78, 0x20, 0x2d, 0x20, 0x28, 0x61, 0x65,
-  0x78, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78, 0x2e, 0x73,
-  0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x20, 0x65, 0x72, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x65, 0x72, 0x72,
-  0x78, 0x20, 0x2d, 0x20, 0x28, 0x61, 0x65, 0x78, 0x2e, 0x73, 0x31, 0x20,
-  0x2a, 0x20, 0x62, 0x65, 0x78, 0x2e, 0x73, 0x30, 0x29, 0x3b, 0x0a, 0x20,
+  0x3d, 0x20, 0x63, 0x20, 0x2d, 0x20, 0x61, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61, 0x68, 0x69, 0x20,
+  0x3d, 0x20, 0x63, 0x20, 0x2d, 0x20, 0x61, 0x62, 0x69, 0x67, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x61,
+  0x6c, 0x6f, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2d, 0x20, 0x61, 0x68, 0x69,
+  0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
+  0x6e, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x61,
+  0x68, 0x69, 0x2c, 0x20, 0x61, 0x6c, 0x6f, 0x29, 0x3b, 0x0d, 0x0a, 0x7d,
+  0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74,
+  0x77, 0x6f, 0x50, 0x72, 0x6f, 0x64, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x20, 0x61, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x29,
+  0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x20, 0x78, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a, 0x20, 0x62, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
+  0x20, 0x61, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x73, 0x70, 0x6c, 0x69, 0x74,
+  0x28, 0x61, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
+  0x6f, 0x61, 0x74, 0x32, 0x20, 0x62, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x73,
+  0x70, 0x6c, 0x69, 0x74, 0x28, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x72, 0x72, 0x78,
+  0x20, 0x3d, 0x20, 0x78, 0x20, 0x2d, 0x20, 0x28, 0x61, 0x65, 0x78, 0x2e,
+  0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78, 0x2e, 0x73, 0x30, 0x29,
+  0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x20, 0x65, 0x72, 0x72, 0x79, 0x20, 0x3d, 0x20, 0x65, 0x72, 0x72, 0x78,
+  0x20, 0x2d, 0x20, 0x28, 0x61, 0x65, 0x78, 0x2e, 0x73, 0x31, 0x20, 0x2a,
+  0x20, 0x62, 0x65, 0x78, 0x2e, 0x73, 0x30, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
   0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x72, 0x72,
   0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x65, 0x72, 0x72,
   0x7a, 0x20, 0x3d, 0x20, 0x65, 0x72, 0x72, 0x79, 0x20, 0x2d, 0x20, 0x28,
   0x7a, 0x20, 0x3d, 0x20, 0x65, 0x72, 0x72, 0x79, 0x20, 0x2d, 0x20, 0x28,
   0x61, 0x65, 0x78, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78,
   0x61, 0x65, 0x78, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78,
-  0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x65, 0x78,
-  0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78, 0x2e, 0x73, 0x31,
-  0x29, 0x20, 0x2d, 0x20, 0x65, 0x72, 0x72, 0x7a, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x78, 0x2c, 0x20, 0x79, 0x29, 0x3b,
-  0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61,
-  0x64, 0x64, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x2c,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x72,
-  0x20, 0x3d, 0x20, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2b, 0x20, 0x62, 0x2e,
-  0x73, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x20, 0x73, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20,
-  0x28, 0x66, 0x61, 0x62, 0x73, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x29, 0x20,
-  0x3e, 0x3d, 0x20, 0x66, 0x61, 0x62, 0x73, 0x28, 0x62, 0x2e, 0x73, 0x30,
-  0x29, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x73, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x28, 0x61, 0x2e, 0x73, 0x30,
-  0x20, 0x2d, 0x20, 0x72, 0x29, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30,
-  0x29, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x20, 0x2b, 0x20,
-  0x61, 0x2e, 0x73, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0a, 0x20,
+  0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x79, 0x20, 0x3d, 0x20, 0x28, 0x61, 0x65,
+  0x78, 0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62, 0x65, 0x78, 0x2e, 0x73,
+  0x31, 0x29, 0x20, 0x2d, 0x20, 0x65, 0x72, 0x72, 0x7a, 0x3b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x28,
+  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x78, 0x2c, 0x20, 0x79,
+  0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x32, 0x20, 0x61, 0x64, 0x64, 0x28, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x32, 0x20, 0x61, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
+  0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x2e, 0x73,
+  0x30, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x3b, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x73, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x66, 0x61, 0x62,
+  0x73, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x29, 0x20, 0x3e, 0x3d, 0x20, 0x66,
+  0x61, 0x62, 0x73, 0x28, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x29, 0x20, 0x7b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x20,
+  0x3d, 0x20, 0x28, 0x28, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x20, 0x2d, 0x20,
+  0x72, 0x29, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x20, 0x2b,
+  0x20, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x61, 0x2e, 0x73,
+  0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65, 0x20, 0x7b, 0x0d, 0x0a, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x28,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x20, 0x3d, 0x20, 0x28,
   0x28, 0x28, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x2d, 0x20, 0x72, 0x29, 0x20,
   0x28, 0x28, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x2d, 0x20, 0x72, 0x29, 0x20,
   0x2b, 0x20, 0x61, 0x2e, 0x73, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x61, 0x2e,
   0x2b, 0x20, 0x61, 0x2e, 0x73, 0x30, 0x29, 0x20, 0x2b, 0x20, 0x61, 0x2e,
-  0x73, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x31, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x7d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
-  0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x53, 0x75, 0x6d, 0x28,
-  0x72, 0x2c, 0x20, 0x73, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x32, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x66, 0x6c, 0x6f,
-  0x61, 0x74, 0x32, 0x20, 0x61, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
-  0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x77,
-  0x6f, 0x50, 0x72, 0x6f, 0x64, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x2c, 0x20,
-  0x62, 0x2e, 0x73, 0x30, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66,
-  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x28,
-  0x61, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x2e, 0x73, 0x31, 0x29,
-  0x20, 0x2b, 0x20, 0x28, 0x61, 0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62,
-  0x2e, 0x73, 0x30, 0x29, 0x29, 0x20, 0x2b, 0x20, 0x74, 0x2e, 0x73, 0x31,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
-  0x20, 0x74, 0x77, 0x6f, 0x53, 0x75, 0x6d, 0x28, 0x74, 0x2e, 0x73, 0x30,
-  0x2c, 0x20, 0x74, 0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x6d, 0x75, 0x6c, 0x46, 0x6c,
-  0x6f, 0x61, 0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61,
-  0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x29, 0x20, 0x7b,
+  0x73, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x31, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x53, 0x75,
+  0x6d, 0x28, 0x72, 0x2c, 0x20, 0x73, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d,
+  0x0a, 0x0d, 0x0a, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x6d, 0x75,
+  0x6c, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x2c, 0x20,
+  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d,
   0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
   0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
   0x74, 0x20, 0x3d, 0x20, 0x74, 0x77, 0x6f, 0x50, 0x72, 0x6f, 0x64, 0x28,
   0x74, 0x20, 0x3d, 0x20, 0x74, 0x77, 0x6f, 0x50, 0x72, 0x6f, 0x64, 0x28,
-  0x61, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0a, 0x20, 0x20,
-  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x33, 0x20, 0x3d,
-  0x20, 0x28, 0x61, 0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62, 0x29, 0x20,
-  0x2b, 0x20, 0x74, 0x2e, 0x73, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20,
-  0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x77, 0x6f, 0x53, 0x75,
-  0x6d, 0x28, 0x74, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x74, 0x2e, 0x73, 0x31,
-  0x29, 0x3b, 0x0a, 0x7d, 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, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x31, 0x2c, 0x20,
-  0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x78, 0x32, 0x2c, 0x20, 0x66, 0x6c,
-  0x6f, 0x61, 0x74, 0x20, 0x79, 0x31, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x20, 0x79, 0x32, 0x2c, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x61, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
+  0x74, 0x33, 0x20, 0x3d, 0x20, 0x28, 0x28, 0x61, 0x2e, 0x73, 0x30, 0x20,
+  0x2a, 0x20, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x61,
+  0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x29, 0x29,
+  0x20, 0x2b, 0x20, 0x74, 0x2e, 0x73, 0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x77, 0x6f,
+  0x53, 0x75, 0x6d, 0x28, 0x74, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x74, 0x2e,
+  0x73, 0x31, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a, 0x0d, 0x0a, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x6d, 0x75, 0x6c, 0x46, 0x6c, 0x6f,
+  0x61, 0x74, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x2c,
+  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
+  0x74, 0x20, 0x3d, 0x20, 0x74, 0x77, 0x6f, 0x50, 0x72, 0x6f, 0x64, 0x28,
+  0x61, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x62, 0x29, 0x3b, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x74, 0x33, 0x20,
+  0x3d, 0x20, 0x28, 0x61, 0x2e, 0x73, 0x31, 0x20, 0x2a, 0x20, 0x62, 0x29,
+  0x20, 0x2b, 0x20, 0x74, 0x2e, 0x73, 0x31, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x74, 0x77, 0x6f,
+  0x53, 0x75, 0x6d, 0x28, 0x74, 0x2e, 0x73, 0x30, 0x2c, 0x20, 0x74, 0x2e,
+  0x73, 0x31, 0x29, 0x3b, 0x0d, 0x0a, 0x7d, 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, 0x20, 0x20, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x77,
-  0x31, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x77, 0x32,
-  0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x68, 0x31, 0x2c,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x68, 0x32, 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, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x78, 0x20, 0x3d, 0x20, 0x69, 0x6e,
-  0x64, 0x65, 0x78, 0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b,
-  0x0a, 0x20, 0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x79, 0x20,
-  0x3d, 0x20, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69,
-  0x64, 0x74, 0x68, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x20, 0x78, 0x31, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20,
+  0x78, 0x32, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x20, 0x79, 0x31,
+  0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 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, 0x66,
+  0x6c, 0x6f, 0x61, 0x74, 0x20, 0x70, 0x77, 0x31, 0x2c, 0x20, 0x66, 0x6c,
+  0x6f, 0x61, 0x74, 0x20, 0x70, 0x77, 0x32, 0x2c, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x20, 0x70, 0x68, 0x31, 0x2c, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x20, 0x70, 0x68, 0x32, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x6d,
+  0x61, 0x78, 0x2c, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x73, 0x6d, 0x6f, 0x6f,
+  0x74, 0x68, 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, 0x69, 0x6e, 0x64, 0x65, 0x78,
+  0x20, 0x25, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0d, 0x0a, 0x20,
+  0x20, 0x20, 0x20, 0x69, 0x6e, 0x74, 0x20, 0x70, 0x79, 0x20, 0x3d, 0x20,
+  0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x2f, 0x20, 0x77, 0x69, 0x64, 0x74,
+  0x68, 0x3b, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c,
   0x6f, 0x61, 0x74, 0x32, 0x20, 0x78, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x66,
   0x6f, 0x61, 0x74, 0x32, 0x20, 0x78, 0x6c, 0x20, 0x3d, 0x20, 0x28, 0x66,
   0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x78, 0x31, 0x2c, 0x20, 0x78,
   0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x78, 0x31, 0x2c, 0x20, 0x78,
-  0x32, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x32, 0x20, 0x79, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f,
-  0x61, 0x74, 0x32, 0x29, 0x28, 0x79, 0x31, 0x2c, 0x20, 0x79, 0x32, 0x29,
-  0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
-  0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58,
+  0x32, 0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x32, 0x20, 0x79, 0x74, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c,
+  0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x79, 0x31, 0x2c, 0x20, 0x79, 0x32,
+  0x29, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x32, 0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c,
+  0x65, 0x58, 0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
+  0x29, 0x28, 0x70, 0x77, 0x31, 0x2c, 0x20, 0x70, 0x77, 0x32, 0x29, 0x3b,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
+  0x20, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59,
   0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28,
   0x20, 0x3d, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28,
-  0x70, 0x77, 0x31, 0x2c, 0x20, 0x70, 0x77, 0x32, 0x29, 0x3b, 0x0a, 0x20,
-  0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x70, 0x69,
-  0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x20, 0x3d, 0x20,
-  0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x70, 0x68, 0x31,
-  0x2c, 0x20, 0x70, 0x68, 0x32, 0x29, 0x3b, 0x0a, 0x0a, 0x20, 0x20, 0x20,
-  0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x20, 0x3d, 0x20,
-  0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c, 0x46, 0x6c, 0x6f, 0x61, 0x74,
-  0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x58,
-  0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20, 0x70, 0x78,
-  0x29, 0x2c, 0x20, 0x78, 0x6c, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x62, 0x20, 0x3d, 0x20,
-  0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c, 0x46, 0x6c, 0x6f, 0x61, 0x74,
-  0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x59,
-  0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x29, 0x20, 0x70, 0x79,
-  0x29, 0x2c, 0x20, 0x79, 0x74, 0x29, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x63, 0x61, 0x20, 0x3d,
-  0x20, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x32, 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,
+  0x70, 0x68, 0x31, 0x2c, 0x20, 0x70, 0x68, 0x32, 0x29, 0x3b, 0x0d, 0x0a,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32,
+  0x20, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x6d, 0x75, 0x6c,
+  0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x29, 0x20, 0x70, 0x78, 0x29, 0x2c, 0x20, 0x78, 0x6c, 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, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74,
+  0x32, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x61, 0x64, 0x64, 0x28, 0x6d, 0x75,
+  0x6c, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c,
+  0x53, 0x63, 0x61, 0x6c, 0x65, 0x59, 0x2c, 0x20, 0x28, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 0x29, 0x20, 0x70, 0x79, 0x29, 0x2c, 0x20, 0x79, 0x74, 0x29,
+  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, 0x66, 0x6c, 0x6f, 0x61,
+  0x74, 0x32, 0x20, 0x63, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x3b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x63,
+  0x62, 0x20, 0x3d, 0x20, 0x62, 0x3b, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20, 0x61, 0x61, 0x20, 0x3d,
   0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 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, 0x66, 0x6c, 0x6f, 0x61,
-  0x74, 0x32, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 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, 0x2e, 0x73, 0x30, 0x20, 0x2b, 0x20, 0x61, 0x61,
-  0x2e, 0x73, 0x31, 0x20, 0x2b, 0x20, 0x62, 0x62, 0x2e, 0x73, 0x30, 0x20,
-  0x2b, 0x20, 0x62, 0x62, 0x2e, 0x73, 0x31, 0x20, 0x3e, 0x20, 0x31, 0x36,
-  0x29, 0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x20,
+  0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61, 0x2c, 0x20, 0x61, 0x29, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f,
+  0x61, 0x74, 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, 0x66, 0x6c, 0x6f, 0x61, 0x74, 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, 0x2e, 0x73, 0x30, 0x20, 0x2b,
+  0x20, 0x62, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x3e, 0x20, 0x31, 0x36, 0x29,
+  0x20, 0x62, 0x72, 0x65, 0x61, 0x6b, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x32, 0x20,
   0x6d, 0x69, 0x6e, 0x75, 0x73, 0x62, 0x62, 0x20, 0x3d, 0x20, 0x28, 0x66,
   0x6d, 0x69, 0x6e, 0x75, 0x73, 0x62, 0x62, 0x20, 0x3d, 0x20, 0x28, 0x66,
   0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x2d, 0x62, 0x62, 0x2e, 0x73,
   0x6c, 0x6f, 0x61, 0x74, 0x32, 0x29, 0x28, 0x2d, 0x62, 0x62, 0x2e, 0x73,
-  0x30, 0x2c, 0x20, 0x2d, 0x62, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0a,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d, 0x20,
-  0x61, 0x64, 0x64, 0x28, 0x61, 0x64, 0x64, 0x28, 0x61, 0x61, 0x2c, 0x20,
-  0x6d, 0x69, 0x6e, 0x75, 0x73, 0x62, 0x62, 0x29, 0x2c, 0x20, 0x63, 0x61,
-  0x29, 0x3b, 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,
-  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, 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, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x61, 0x2e, 0x73, 0x30,
-  0x20, 0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x2e,
-  0x73, 0x30, 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, 0x65, 0x6c, 0x73, 0x65, 0x0a, 0x20,
+  0x30, 0x2c, 0x20, 0x2d, 0x62, 0x62, 0x2e, 0x73, 0x31, 0x29, 0x3b, 0x0d,
+  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x61, 0x20, 0x3d,
+  0x20, 0x61, 0x64, 0x64, 0x28, 0x61, 0x64, 0x64, 0x28, 0x61, 0x61, 0x2c,
+  0x20, 0x6d, 0x69, 0x6e, 0x75, 0x73, 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, 0x0d, 0x0a, 0x20,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41,
   0x5b, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x5d, 0x20, 0x3d, 0x20, 0x28, 0x28,
   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, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20,
+  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, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x61, 0x2e, 0x73, 0x30, 0x20,
+  0x2b, 0x20, 0x62, 0x2e, 0x73, 0x30, 0x20, 0x2a, 0x20, 0x62, 0x2e, 0x73,
+  0x30, 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, 0x65, 0x6c, 0x73, 0x65, 0x0d, 0x0a,
   0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
   0x20, 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, 0x20, 0x2b,
-  0x20, 0x31, 0x20, 0x2d, 0x20, 0x28, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20,
-  0x2b, 0x20, 0x62, 0x20, 0x2a, 0x20, 0x62, 0x20, 0x2d, 0x20, 0x31, 0x36,
-  0x29, 0x20, 0x2f, 0x20, 0x28, 0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x31,
-  0x36, 0x29, 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20,
-  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x67,
-  0x65, 0x74, 0x5f, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64,
-  0x28, 0x30, 0x29, 0x5d, 0x20, 0x3d, 0x20, 0x35, 0x3b, 0x0a, 0x7d, 0x0a
+  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 doublefloat_cl_len = 2820;
+unsigned int doublefloat_cl_len = 2770;

+ 121 - 0
libmandel/src/opencl/fixed512.cl

@@ -0,0 +1,121 @@
+
+
+/*uint16 add(uint16 a, uint16 b) {
+    uint mask = 0x00FFFFFF;
+}*/
+
+
+ulong2 add(ulong2 a, ulong2 b) {
+    ulong2 result;
+    uchar carry = 0;
+    for (int i = 1; i >= 0; i--) {
+        uchar tmpcr = carry;
+        ulong temp = a[i] + b[i];
+        carry = (hadd(a[i], b[i]) >> 63) | (hadd(temp, (ulong) carry) >> 63);
+        temp += tmpcr;
+        result[i] = temp;
+    }
+    return result;
+}
+
+ulong2 sub(ulong2 a, ulong2 b) {
+    ulong lowerSubbed = a[1] - b[1];
+    ulong upperSubbed = a[0] - b[1] - ((lowerSubbed > a[1]) ? 1 : 0);
+    return (ulong2)(upperSubbed, lowerSubbed);
+}
+
+/*
+ulong4 mulPart(ulong2 a, ulong b) {
+    ulong4 result;
+    ulong carry = 0;
+    for (int i = 1; i >= 0; i--) {
+        ulong lower = a[i] * b[i];
+        ulong upper = mul_hi(a[i], b[i]);
+        ulong c = lower + carry;
+        ulong cc = hadd(lower, carry) >> 63;
+        carry = upper + cc;
+        result[i] = c;
+    }
+}*/
+
+ulong2 mulu64(ulong a, ulong b) {
+    return (ulong2)(mul_hi(a, b), a * b);
+}
+
+ulong2 mul(ulong2 a, ulong2 b) {
+    //uint4 avec = (uint4)(a[0] >> 32, a[0], a[1] >> 32, a[1]);
+    //uint4 bvec = (uint4)(b[0] >> 32, b[0], b[1] >> 32, b[1]);
+
+    ulong2 uu = mulu64(a[0], b[0]);
+    ulong2 ul = mulu64(a[0], b[1]);
+    ulong2 lu = mulu64(a[1], b[0]);
+    ulong2 ll = mulu64(a[1], b[1]);
+
+    ulong4 res = (ulong4)(0, 0, 0, 0);
+    res[3] = ll[1];
+    res[2] += lu[1];
+    res[2] += ul[1];
+    if (res[2] < ul[1])
+        res[1]++;
+    res[2] += ll[0];
+    if (res[2] < ll[0])
+        res[1]++;
+    res[1] += uu[1];
+    if (res[1] < uu[1])
+        res[0]++;
+    res[1] += ul[0];
+    if (res[1] < ul[0])
+        res[0]++;
+    res[1] += lu[0];
+    if (res[1] < lu[0])
+        res[0]++;
+    res[0] += uu[0];
+
+    uint4 num = (uint4) (res[0] & 0xFFFFFFFF, ((long) res[1]) >> 32, res[1] & 0xFFFFFFFF, ((long) res[2]) >> 32);
+    return (ulong2)((num[0] << 32) + num[1], (num[2] << 32) + num[3]);
+}
+
+
+__kernel void iterate(__global float* A, const int width,
+                      ulong x1, ulong x2, ulong y1, ulong y2,
+                      ulong pw1, ulong pw2, ulong ph1, ulong ph2, int max, int smooth) {
+    int index = get_global_id(0);
+    ulong2 px = (ulong2) ((index % width) << 32, 0);
+    ulong2 py = (ulong2) ((index / width) << 32, 0);
+
+    ulong2 xl = (ulong2)(x1, x2);
+    ulong2 yt = (ulong2)(y1, y2);
+    ulong2 pixelScaleX = (ulong2)(pw1, pw2);
+    ulong2 pixelScaleY = (ulong2)(ph1, ph2);
+
+    ulong2 a = add(mul(pixelScaleX, px), xl); // pixelScaleX * px + xl
+    ulong2 b = add(mul(pixelScaleY, py), yt); // pixelScaleY * py + yt
+    ulong2 ca = a;
+    ulong2 cb = b;
+
+    int n = 0;
+    while (n < max - 1) {
+        ulong2 aa = mul(a, a);
+        ulong2 bb = mul(b, b);
+        ulong2 ab = mul(a, b);
+        if (aa.s0 + aa.s1 + bb.s0 + bb.s1 > 16) break;
+        a = add(sub(aa, bb), ca);
+        b = add(add(ab, ab), cb);
+        n++;
+    }
+
+    // N + 1 - log (log  |Z(N)|) / log 2
+    if (n >= max - 1)
+        A[index] = max;
+    else {
+        if (smooth != 0) {
+            float aapprox = (float) a.s0 * 2.3283064e-10f;
+            float bapprox = (float) b.s0 * 2.3283064e-10f;
+            A[index] = ((float) n) + 1 - log(log(aapprox * aapprox + bapprox * bapprox) / 2) / log(2.0f);
+        }
+        else
+            A[index] = ((float)n);
+    }
+    //               A[index] = ((float)n) + 1 - (a * a + b * b - 16) / (256 - 16);
+    //           A[get_global_id(0)] = 5;
+}

+ 298 - 0
libmandel/src/opencl/fixed512.h

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

+ 51 - 0
libmandel/src/opencl/fixed64.cl

@@ -0,0 +1,51 @@
+
+
+long mul(long a, long b) {
+    long upper = mul_hi(a, b);
+    long lower = a * b;
+    return (upper << 32) + ((lower >> 32) & 0xFFFFFFFF);
+}
+
+
+__kernel void iterate(__global float* A, const int width,
+                      ulong x, ulong y, ulong pw, ulong ph, int max, int smooth) {
+    int index = get_global_id(0);
+    long px = (index % width) << 48;
+    long py = (index / width) << 48;
+
+    long xl = x;
+    long yt = y;
+    long pixelScaleX = pw;
+    long pixelScaleY = ph;
+
+    long a = (mul(pixelScaleX, px) + xl); // pixelScaleX * px + xl
+    long b = (mul(pixelScaleY, py) + yt); // pixelScaleY * py + yt
+    long ca = a;
+    long cb = b;
+
+    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;
+        n++;
+    }
+
+    // N + 1 - log (log  |Z(N)|) / log 2
+    if (n >= max - 1)
+        A[index] = max;
+    else {
+        if (smooth != 0) {
+            float aapprox = ((float) a) * 3.5527137e-15f;
+            float bapprox = ((float) b) * 3.5527137e-15f;
+            A[index] = ((float) n) + 1 - log(log(aapprox * aapprox + bapprox * bapprox) / 2) / log(2.0f);
+        }
+        else
+            A[index] = ((float)n);
+    }
+    //               A[index] = ((float)n) + 1 - (a * a + b * b - 16) / (256 - 16);
+    //           A[get_global_id(0)] = 5;
+}

+ 127 - 0
libmandel/src/opencl/fixed64.h

@@ -0,0 +1,127 @@
+unsigned char fixed64_cl[] = {
+  0x0d, 0x0a, 0x0d, 0x0a, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x6d, 0x75, 0x6c,
+  0x28, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x2c, 0x20, 0x6c, 0x6f, 0x6e,
+  0x67, 0x20, 0x62, 0x29, 0x20, 0x7b, 0x0d, 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, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67,
+  0x20, 0x6c, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x3d, 0x20, 0x61, 0x20, 0x2a,
+  0x20, 0x62, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65, 0x74,
+  0x75, 0x72, 0x6e, 0x20, 0x28, 0x75, 0x70, 0x70, 0x65, 0x72, 0x20, 0x3c,
+  0x3c, 0x20, 0x33, 0x32, 0x29, 0x20, 0x2b, 0x20, 0x28, 0x28, 0x6c, 0x6f,
+  0x77, 0x65, 0x72, 0x20, 0x3e, 0x3e, 0x20, 0x33, 0x32, 0x29, 0x20, 0x26,
+  0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 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, 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, 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,
+  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, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x3b, 0x0d, 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, 0x20, 0x3c, 0x3c, 0x20, 0x34, 0x38, 0x3b, 0x0d, 0x0a,
+  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x78,
+  0x6c, 0x20, 0x3d, 0x20, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x79, 0x74, 0x20, 0x3d, 0x20, 0x79, 0x3b,
+  0x0d, 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, 0x0d, 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, 0x0d, 0x0a, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x61, 0x20, 0x3d,
+  0x20, 0x28, 0x6d, 0x75, 0x6c, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53,
+  0x63, 0x61, 0x6c, 0x65, 0x58, 0x2c, 0x20, 0x70, 0x78, 0x29, 0x20, 0x2b,
+  0x20, 0x78, 0x6c, 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, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
+  0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x62, 0x20, 0x3d, 0x20, 0x28, 0x6d, 0x75,
+  0x6c, 0x28, 0x70, 0x69, 0x78, 0x65, 0x6c, 0x53, 0x63, 0x61, 0x6c, 0x65,
+  0x59, 0x2c, 0x20, 0x70, 0x79, 0x29, 0x20, 0x2b, 0x20, 0x79, 0x74, 0x29,
+  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,
+  0x20, 0x63, 0x61, 0x20, 0x3d, 0x20, 0x61, 0x3b, 0x0d, 0x0a, 0x20, 0x20,
+  0x20, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x20, 0x63, 0x62, 0x20, 0x3d, 0x20,
+  0x62, 0x3b, 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, 0x20, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x6d, 0x75, 0x6c, 0x28, 0x61,
+  0x2c, 0x20, 0x61, 0x29, 0x3b, 0x0d, 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, 0x0d,
+  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, 0x0d, 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, 0x0d, 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, 0x0d, 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, 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, 0x29, 0x20, 0x2a, 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, 0x29, 0x20, 0x2a, 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, 0x20,
+  0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 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, 0x20, 0x2b, 0x20, 0x31, 0x20, 0x2d, 0x20,
+  0x28, 0x61, 0x20, 0x2a, 0x20, 0x61, 0x20, 0x2b, 0x20, 0x62, 0x20, 0x2a,
+  0x20, 0x62, 0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x20, 0x2f, 0x20, 0x28,
+  0x32, 0x35, 0x36, 0x20, 0x2d, 0x20, 0x31, 0x36, 0x29, 0x3b, 0x0d, 0x0a,
+  0x20, 0x20, 0x20, 0x20, 0x2f, 0x2f, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+  0x20, 0x20, 0x20, 0x20, 0x20, 0x41, 0x5b, 0x67, 0x65, 0x74, 0x5f, 0x67,
+  0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x28, 0x30, 0x29, 0x5d,
+  0x20, 0x3d, 0x20, 0x35, 0x3b, 0x0d, 0x0a, 0x7d, 0x0d, 0x0a
+};
+unsigned int fixed64_cl_len = 1486;