/// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            // https://github.com/tumblr/jumblr

            new Abstractatech.ConsoleFormPackage.Library.ConsoleForm()
                .InitializeConsoleFormWriter()
                .PopupInsteadOfClosing()
                .Show();


            // 
            new IHTMLIFrame
            {
                src = "http://www.whatsmyip.us/",
                //src = "http://whatsmyip.net/", 
                frameBorder = "0",
                scrolling = "no",
                width = 400,
                height = 72
            }.AttachToDocument().style.SetSize(
                400, 72);

            new IHTMLBreak().AttachToDocument();

            //new IHTMLButton { innerText = "swapCache" }.AttachToDocument().WhenClicked(
            //    delegate
            //    {
            //        // Uncaught InvalidStateError: Failed to execute 'swapCache' on 'ApplicationCache': there is no newer application cache to swap to.
            //        Native.window.applicationCache.swapCache();
            //    }
            //);


            @"Hello world".ToDocumentTitle();
            // Send data from JavaScript to the server tier

            service.getNumberOfCameras(
                cameras =>
                {

                    Enumerable.Range(0, int.Parse(cameras)).Select(i => new { i }).WithEach(
                        ii =>
                        {
                            var i = ii.i;
                            new IHTMLBreak().AttachToDocument();

                            #region show me stills
                            new IHTMLButton { innerText = "show me stills " + new { i } }.AttachToDocument().onclick +=
                                delegate
                                {
                                    service.WebMethod2(
                                        "" + i,
                                        value =>
                                        {
                                            if (!value.StartsWith("data:"))
                                            {
                                                Console.WriteLine(value);
                                                return;
                                            }

                                            new IHTMLImage { src = value }.AttachToDocument();
                                        }
                                    );
                                };
                            #endregion


                            #region show me animation


                            new IHTMLButton { innerText = "show me animation" }.AttachToDocument().onclick +=
                                delegate
                                {
                                    var img = new IHTMLImage { }.AttachToDocument();

                                    var data = new List<string>();

                                    service.WebMethod2(
                                       "" + i,
                                        value =>
                                        {
                                            if (!value.StartsWith("data:"))
                                            {
                                                Console.WriteLine(value);
                                                return;
                                            }

                                            data.Add(value);
                                        }
                                    );

                                    new Timer(
                                        t =>
                                        {
                                            if (data.Count == 0)
                                                return;

                                            img.src = data[t.Counter % data.Count];
                                        }
                                    ).StartInterval(1000 / 15);
                                };
                            #endregion


                            #region show me animation async
                            new IHTMLButton { innerText = "show me animation async" }.AttachToDocument().onclick +=
                                 delegate
                                 {



                                     var img = new IHTMLImage { }.AttachToDocument();

                                     var data = new List<string>();



                                     service.async_WebMethod2(
                                        "" + i,
                                         value =>
                                         {
                                             if (!value.StartsWith("data:"))
                                             {
                                                 Console.WriteLine(value);
                                                 return;
                                             }

                                             data.Add(value);


                                         }

                                     );

                                     new Timer(
                                         t =>
                                         {
                                             if (data.Count == 0)
                                                 return;

                                             img.src = data[t.Counter % data.Count];
                                         }
                                     ).StartInterval(1000 / 15);
                                 };
                            #endregion

                            #region show me animation async and gif it
                            new IHTMLButton { innerText = "gif it " + new { i } }.AttachToDocument().onclick +=
                                 delegate
                                 {
                                     Console.WriteLine("working...");


                                     new IHTMLBreak().AttachToDocument();

                                     var img = new IHTMLImage { }.AttachToDocument();

                                     var data = new List<string>();

                                     var gifmaxframes = 60;

                                     #region Timer
                                     new Timer(
                                         t =>
                                         {
                                             if (data.Count == 0)
                                                 return;

                                             if (data.Count < gifmaxframes)
                                             {
                                                 img.src = data.Last();
                                                 return;
                                             }

                                             img.src = data[t.Counter % data.Count];
                                         }
                                     ).StartInterval(1000 / 15);
                                     #endregion


                                     var c0 = new CanvasRenderingContext2D();

                                     // no scale!
                                     c0.canvas.width = 320;
                                     c0.canvas.height = 240;
                                     c0.canvas.style.SetSize(320, 240);



                                     var c1 = new CanvasRenderingContext2D();

                                     // no scale!
                                     c1.canvas.width = 320;
                                     c1.canvas.height = 240;
                                     c1.canvas.style.SetSize(320, 240);

                                     //c0.canvas.AttachToDocument();


                                     // http://stackoverflow.com/questions/1864756/web-workers-and-canvas

                                     service.async_WebMethod2(
                                         "" + i,
                                         value =>
                                         {
                                             if (!value.StartsWith("data:"))
                                             {
                                                 Console.WriteLine(value);
                                                 return;
                                             }

                                             data.Add(value);



                                             if (data.Count == gifmaxframes)
                                             {
                                                 // need webworker!

                                                 #region gif
                                                 var st = new Stopwatch();
                                                 st.Start();

                                                 var encoder1 = new GIFEncoderAsync(
                                                     320, 240
                                                 );

                                                 //encoder1.setRepeat(0); //auto-loop
                                                 //encoder1.setDelay(1000 / 15);
                                                 //encoder1.start();

                                                 var encoder2 = new GIFEncoderAsync(
                                                     320, 240
                                                 );

                                                 //encoder2.setRepeat(0); //auto-loop
                                                 //encoder2.setDelay(1000 / 15);
                                                 //encoder2.start();

                                                 #region frames
                                                 Console.WriteLine("gif " + new { st.Elapsed });

                                                 for (int datai = 0; datai < data.Count; datai++)
                                                 {
                                                     Console.WriteLine("gif " + new { datai, st.Elapsed });

                                                     c1.drawImage(new IHTMLImage { src = data[datai] }, 0, 0, 320, 240);
                                                     encoder2.addFrame(c1);


                                                     c0.drawImage(new IHTMLImage { src = data[datai] }, 0, 0, 320, 240);

                                                     #region grayscale
                                                     var imageData = c0.getImageData(0, 0, 320, 240);

                                                     // This loop gets every pixels on the image and
                                                     for (var j = 0; j < imageData.width; j++)
                                                     {
                                                         for (var ji = 0; ji < imageData.height; ji++)
                                                         {
                                                             var index = (uint)((ji * 4) * imageData.width + (j * 4));
                                                             var red = imageData.data[index];
                                                             var green = imageData.data[index + 1];
                                                             var blue = imageData.data[index + 2];
                                                             var alpha = imageData.data[index + 3];
                                                             var average = (byte)((red + green + blue) / 3);

                                                             imageData.data[index] = average;
                                                             imageData.data[index + 1] = average;
                                                             imageData.data[index + 2] = average;

                                                             //imageData.data[index + 1] = average;
                                                             //imageData.data[index + 2] = average;

                                                             imageData.data[index + 3] = alpha;
                                                         }
                                                     }

                                                     // overwrite original image
                                                     c0.putImageData(imageData, 0, 0, 0, 0, 320, 240);
                                                     #endregion


                                                     encoder1.addFrame(c0);

                                                     Console.WriteLine("gif done " + new { datai, st.Elapsed });

                                                 }


                                                 encoder1.finish(
                                                 src =>
                                                 {
                                                     var image = new IHTMLImage();
                                                     image.src = src;
                                                     image.style.SetSize(640, 480);

                                                     Console.WriteLine("gif got src" + new { st.Elapsed });

                                                     image.AttachToDocument();
                                                 }
                                                 );
                                                 encoder2.finish(
                                                 src =>
                                                 {
                                                     var image = new IHTMLImage();

                                                     image.src = src;
                                                     image.style.SetSize(640, 480);

                                                     Console.WriteLine("gif got src" + new { st.Elapsed });

                                                     image.AttachToDocument();
                                                 }
                                                 );
                                                 #endregion


                                                 #endregion



                                             }
                                         }

                                     );

                                 };
                            #endregion





                        }
                    );




                }
            );


            new IHTMLBreak().AttachToDocument();
        }
        public Application(IApp page)
        {
            // how does this worK?
            // run it to see what we have?
            // seems to work. but laptp is freezing up????

            new forest5().With(
                async img =>
                {

                    await img;

                    var st0 = new Stopwatch();
                    st0.Start();
                    var c0 = new CanvasRenderingContext2D(
                         img.width,
                         img.height
                     );


                    c0.drawImage(img, 0, 0, img.width, img.height);
                    var imageData = c0.getImageData(0, 0, img.width, img.height);

                    var AnimatedColors = new List<int> {
                        0x3C4C8C,
                        0x2C407C,
                        0x2C3C84,
                        0x20306C
                    };



                    #region f
                    Func<int[], Task<CanvasRenderingContext2D>> f =
                         AnimatedColorsTo =>
                         {

                             var c1 = new CanvasRenderingContext2D(
                                  img.width,
                                  img.height
                              );



                             var imageData1 = c1.getImageData(0, 0, img.width, img.height);

                             // This loop gets every pixels on the image and
                             for (var j = 0; j < imageData.width; j++)
                             {
                                 for (var ji = 0; ji < imageData.height; ji++)
                                 {
                                     var index = (uint)((ji * 4) * imageData.width + (j * 4));
                                     var red = imageData.data[index];
                                     var green = imageData.data[index + 1];
                                     var blue = imageData.data[index + 2];
                                     var alpha = imageData.data[index + 3];
                                     var average = (byte)((red + green + blue) / 3);

                                     var u8 = (red << 16) + (green << 8) + blue;
                                     var u8i = AnimatedColors.IndexOf(u8);

                                     if (u8i >= 0)
                                     {
                                         u8 = AnimatedColorsTo[u8i];

                                         red = (byte)((u8 >> 16) & 0xff);
                                         green = (byte)((u8 >> 8) & 0xff);
                                         blue = (byte)((u8 >> 0) & 0xff);
                                     }
                                     else
                                     {
                                         alpha = 0x00;
                                     }


                                     // 3C4C8C
                                     // 2C407C
                                     // 20306C

                                     imageData1.data[index] = red;
                                     imageData1.data[index + 1] = green;
                                     imageData1.data[index + 2] = blue;

                                     //imageData.data[index + 1] = average;
                                     //imageData.data[index + 2] = average;

                                     imageData1.data[index + 3] = alpha;
                                 }
                             }

                             // overwrite original image
                             c1.putImageData(imageData1, 0, 0, 0, 0, img.width, img.height);

                             var xx = new TaskCompletionSource<CanvasRenderingContext2D>();
                             xx.SetResult(c1);
                             return xx.Task;

                         };
                    #endregion

                    var st = new Stopwatch();
                    st.Start();

                    //{ ElapsedMilliseconds = 4795 } 

                    var a1 = new[]{
                            AnimatedColors[1],
                            AnimatedColors[2],
                            AnimatedColors[3],
                            AnimatedColors[0],
                        };
                    var o1 = f(a1).Result;


                    var a2 = new[]{
                                    AnimatedColors[2],
                                    AnimatedColors[3],
                                    AnimatedColors[0],
                                    AnimatedColors[1],
                                };
                    var o2 = f(a2).Result;

                    var a3 =
                       new[]{
                                            AnimatedColors[3],
                                            AnimatedColors[0],
                                            AnimatedColors[1],
                                            AnimatedColors[2],
                                        };
                    var o3 = f(a3).Result;

                    Console.WriteLine(new { st.ElapsedMilliseconds });

                    c0.canvas.AttachToDocument().style.SetLocation(0, 0);
                    o1.canvas.AttachToDocument().style.SetLocation(0, 0);
                    o2.canvas.AttachToDocument().style.SetLocation(0, 0);
                    o3.canvas.AttachToDocument().style.SetLocation(0, 0);

                    new Timer(
                        t =>
                        {
                            if (t.Counter % AnimatedColors.Count == 0)
                            {
                                o1.canvas.Hide();
                                o2.canvas.Hide();
                                o3.canvas.Hide();
                                return;
                            }

                            if (t.Counter % AnimatedColors.Count == 1)
                            {
                                o1.canvas.Show();
                                o2.canvas.Hide();
                                o3.canvas.Hide();
                                return;
                            }

                            if (t.Counter % AnimatedColors.Count == 2)
                            {
                                o1.canvas.Hide();
                                o2.canvas.Show();
                                o3.canvas.Hide();
                                return;
                            }

                            if (t.Counter % AnimatedColors.Count == 3)
                            {
                                o1.canvas.Hide();
                                o2.canvas.Hide();
                                o3.canvas.Show();
                                return;
                            }
                        }
                    ).StartInterval(1000 / 5);

                    // { ElapsedMilliseconds = 1843 } 
                    Console.WriteLine("all: " + new { st.ElapsedMilliseconds });
                }
            );
        }
        // X:\jsc.svn\examples\javascript\Test\TestPackageAsApplication\TestPackageAsApplication\Application.cs

        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            Console.WriteLine("before");
            {
                var c = new CanvasRenderingContext2D(256, 256);


                var bytes = new byte[256 * 256 * 4];

                for (int x = 0; x < 256; x++)
                {
                    for (int y = 0; y < 256; y++)
                    {
                        bytes[x * 4 + 0 + 256 * 4 * y] = (byte)x;
                        bytes[x * 4 + 1 + 256 * 4 * y] = (byte)y;
                        bytes[x * 4 + 2 + 256 * 4 * y] = 0xff;
                        bytes[x * 4 + 3 + 256 * 4 * y] = 0xcf;
                    }


                }

                var i = c.getImageData();

                i.data.set(bytes, 0);

                c.putImageData(i, 0, 0, 0, 0, 256, 256);

                c.canvas.AttachToDocument();

            }


            {
                var bytes = new byte[256 * 256 * 4];

                for (int x = 0; x < 256; x++)
                {
                    for (int y = 0; y < 256; y++)
                    {
                        bytes[x * 4 + 0 + 256 * 4 * y] = 0;
                        bytes[x * 4 + 1 + 256 * 4 * y] = 0;
                        bytes[x * 4 + 2 + 256 * 4 * y] = 0;

                        // alpha?
                        bytes[x * 4 + 3 + 256 * 4 * y] = (byte)x;
                    }


                }

                // 1824 of 65536
                // 0.02783203125
                // 262144

                var slider = new IHTMLInput
                {

                    type = ScriptCoreLib.Shared.HTMLInputTypeEnum.range,
                    max = 256 * 256
                }.AttachToDocument();


                new IHTMLPre { 
                    () =>
                    new { 
                        bytes.Length,
                        md5 = bytes.ToMD5Bytes().ToHexString(), 
                        slider.valueAsNumber,
                        u4 = new [] { 
                            bytes[slider.valueAsNumber * 4 + 0],
                            bytes[slider.valueAsNumber * 4 +1],
                            bytes[slider.valueAsNumber * 4 +2],
                            bytes[slider.valueAsNumber * 4 +3]
                        }.ToHexString() }
                }.AttachToDocument();

                var c = new CanvasRenderingContext2D(256, 256) { bytes = bytes };

                c.canvas.AttachToDocument();

                // https://code.google.com/p/chromium/issues/detail?id=312187
                // save for disk saving
                // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement
                var csrc = c.canvas.toDataURL("image/png");
                var csrci = new IHTMLImage { src = csrc }.AttachToDocument();

                // do the reverse
                var z = new CanvasRenderingContext2D(256, 256);
                z.drawImage(csrci, 0, 0, 256, 256);
                z.canvas.AttachToDocument();

                // whats the bytes?

                var zbytes = z.bytes;

                new IHTMLPre { 
                    () =>
                    new {
                        zbytes.Length,
                        
                        md5 = zbytes.ToMD5Bytes().ToHexString() ,
                        slider.valueAsNumber,
                        u4 = new [] { 
                            zbytes[slider.valueAsNumber * 4 + 0],
                            zbytes[slider.valueAsNumber * 4 +1],
                            zbytes[slider.valueAsNumber * 4 +2],
                            zbytes[slider.valueAsNumber * 4 +3]
                        }.ToHexString() 
                    }
                }.AttachToDocument();


                // 00ff80cf vs 00ff7fcf
            }
            Console.WriteLine("after");


            new IHTMLButton { "make me the link " + new { Native.document.location.protocol } }.AttachToDocument().WhenClicked(
               makelink =>
               {
                   makelink.disabled = true;



                   #region PackageAsApplication
                   Action<IHTMLScript, XElement, Action<string>> PackageAsApplication =
                       (source0, xml, yield) =>
                       {
                           new IXMLHttpRequest(
                               ScriptCoreLib.Shared.HTTPMethodEnum.GET,
                               source0.src,
                               handler: (IXMLHttpRequest r) =>
                               {
                                   // store hash
                                   xml.Add(new XElement("link", new XAttribute("rel", "location"), new XAttribute("href", Native.Document.location.hash)));


                                   xml.Add(
                                       new XElement("script",
                                           "/* source */"
                                       )
                                   );

                                   var data = "";


                                   Action later = delegate
                                   {

                                       data = data.Replace("/* source */", r.responseText);

                                   };


                                   //Native.Document.getElementsByTagName("link").AsEnumerable().ToList().ForEach(

                                   xml.Elements("link").ToList().ForEach(
                                       (XElement link, Action next) =>
                                       {
                                           #region style
                                           var rel = link.Attribute("rel");
                                           if (rel.Value != "stylesheet")
                                           {
                                               next();
                                               return;
                                           }

                                           var href = link.Attribute("href");

                                           var placeholder = "/* " + href.Value + " */";

                                           //page.DragHTM.innerText += " " + placeholder;


                                           xml.Add(new XElement("style", placeholder));

                                           new IXMLHttpRequest(ScriptCoreLib.Shared.HTTPMethodEnum.GET, href.Value,
                                               rr =>
                                               {

                                                   later += delegate
                                                   {


                                                       data = data.Replace(placeholder, rr.responseText);

                                                   };

                                                   Console.WriteLine("link Remove");
                                                   link.Remove();

                                                   next();
                                               }
                                           );

                                           #endregion
                                       }
                                   )(
                                       delegate
                                       {


                                           data = xml.ToString();
                                           Console.WriteLine("data: " + data);
                                           later();

                                           yield(data);
                                       }
                                   );
                               }
                           );

                       };
                   #endregion

                   // XMLHttpRequest cannot load file:///D:/view-source. Cross origin requests are only supported for HTTP. 



                   Console.WriteLine("before PackageAsApplication");
                   PackageAsApplication(

                       // how would we know our current source location?
                       new IHTMLScript { src = "view-source" },
                       XElement.Parse(AppSource.Text),
                       async data =>
                       {
                           Console.WriteLine("enter PackageAsApplication");
                           var bytes0 = Encoding.UTF8.GetBytes(data);
                           var w0 = (int)Math.Ceiling(Math.Sqrt(bytes0.Length));

                           var padding0 = (w0 * w0) - bytes0.Length;

                           // { Length = 2072331, padding0 = 1269 }
                           new IHTMLPre {
                               new { 
                                   bytes0.Length, 
                                   padding0
                               }
                           }.AttachToDocument();


                           var bytes = Encoding.UTF8.GetBytes(
                               data

                               +
                               Encoding.UTF8.GetString(new byte[padding0])

                               // too slow?
                               //+ new string(' ', padding0)
                               );

                           //var bytes = Encoding.ASCII.GetBytes(data);

                           // { Length = 2019412 }


                           // why wont intellisense work like excel, debugger
                           // and tell me the anwser without running
                           // the other option is to step in via F11

                           //  Math.Sqrt(2019412) 1421.0601676213432

                           var w = (int)Math.Ceiling(Math.Sqrt(bytes.Length));

                           //{ Length = 2049266, w = 1432 }
                           //{ Length = 8202496 }

                           new IHTMLPre {
                               new { 
                                   bytes.Length, 
                                   w, 
                                   
                                 u8 = new [] { 
                                        bytes[0 * 4 + 0],
                                        bytes[0 * 4 +1],
                                        bytes[0 * 4 +2],
                                        bytes[0 * 4 +3],

                                        bytes[1 * 4 + 0],
                                        bytes[1 * 4 +1],
                                        bytes[1 * 4 +2],
                                        bytes[1 * 4 +3]
                                    }.ToHexString() ,

                                   md5 = bytes.ToMD5Bytes().ToHexString() }
                           }.AttachToDocument();

                           // 77,828 bytes)
                           var wbyteswatch = Stopwatch.StartNew();

                           // { Length = 2069090, w = 1439, u8 = 3c68746d6c3e0a20, md5 = 4fa4af629b63b267da4d4a142c9cb171 }
                           // { Length = 2070721, md5 = 0186a2c2d01257cf4ba6a5524ec4743d, u8 = 3c68746d6c3e0a20 }


                           #region encode
                           var wbytes = await Task.Factory.StartNew(
                               new { bytes, w },
                               scope =>
                               {
                                   // Native.Console.WriteLine += ?

                                   // { Length = 2053956, u4 = 3c68746d } 

                                   Console.WriteLine(
                                    new
                                    {
                                        scope.bytes.Length,

                                        u4 = new[] { 
                                            scope.bytes[0 * 4 + 0],
                                            scope.bytes[0 * 4 +1],
                                            scope.bytes[0 * 4 +2],
                                            scope.bytes[0 * 4 +3]
                                        }.ToHexString()
                                    }
                                   );


                                   // Uncaught Error: InvalidOperationException: { MethodToken = dAAABv_a4OTKgLfLC20SaJA } function is not available at { href =
                                   var ww = scope.w;

                                   var wwbytes = new byte[ww * ww * 4];
                                   var wi = 0;

                                   for (int i = 0; i < wwbytes.Length; i += 4)
                                   {
                                       //bytes[x * 4 + 0 + 256 * 4 * y] = 0;
                                       //bytes[x * 4 + 1 + 256 * 4 * y] = 0;
                                       //bytes[x * 4 + 2 + 256 * 4 * y] = 0;

                                       // can we get a red picture?
                                       // unless we alpha everything out!
                                       // 692 KB!
                                       //wwbytes[i + 0] = (byte)(0xff);
                                       wwbytes[i + 0] = 0;
                                       wwbytes[i + 1] = 0;
                                       wwbytes[i + 2] = 0;
                                       // alpha
                                       wwbytes[i + 3] =

                                           // the bytes histogram seems
                                           // to be in the middle?
                                           scope.bytes[wi];

                                       // reverse alpha?
                                       //(byte)(255 - scope.bytes[wi]);
                                       //(byte)~scope.bytes[wi];

                                       wi++;
                                   }



                                   return wwbytes;
                               }
                           );
                           #endregion


                           //{ Length = 2071072, w = 1440, u4 = 3c68746d, md5 = 5c45e67b07d9045882dfe305e9bf23fd }
                           //{ Length = 8294400, ElapsedMilliseconds = 9971, u8 = ff00003cff00003c }

                           new IHTMLPre {
                               new { 
                                   wbytes.Length, wbyteswatch.ElapsedMilliseconds,
                                    u8 = new [] { 
                                        wbytes[0 * 4 + 0],
                                        wbytes[0 * 4 +1],
                                        wbytes[0 * 4 +2],
                                        wbytes[0 * 4 +3],

                                        wbytes[1 * 4 + 0],
                                        wbytes[1 * 4 +1],
                                        wbytes[1 * 4 +2],
                                        wbytes[1 * 4 +3]
                                    }.ToHexString() 
                               }
                           }.AttachToDocument();


                           new IHTMLPre {
                               new { wbytes.Length, wbyteswatch.ElapsedMilliseconds, md5 = wbytes.ToMD5Bytes().ToHexString() }
                           }.AttachToDocument();

                           // { Length = 8236900, ElapsedMilliseconds = 2476, md5 = 166c1b692fad548789a12a3ae5f0a7ae }

                           var c = new CanvasRenderingContext2D(w, w) { bytes = wbytes };

                           // this would touch our precious alpha channel!

                           //c.fillText(
                           //    "rgb channel for preview, while alpha channel has the data of "
                           //    + new { bytes.Length },
                           //    64, 64, c.canvas.width
                           //    );


                           c.canvas.style.backgroundColor = "yellow";
                           c.canvas.style.border = "1px solid red";
                           c.canvas.AttachToDocument();

                           // https://code.google.com/p/chromium/issues/detail?id=312187
                           // save for disk saving
                           // https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement
                           var csrc = c.canvas.toDataURL("image/png");


                           // this wont help at all
                           // https://bugzilla.mozilla.org/show_bug.cgi?id=676619

                           var csrca = new IHTMLAnchor { download = "view-source.png", href = csrc, title = "view-source", innerText = "do not drag, click to download view-source.png" }.AttachToDocument();
                           // http://caniuse.com/download


                           var csrci = new IHTMLImage { src = csrc }.AttachToDocument();
                           csrci.style.backgroundColor = "yellow";
                           csrci.style.border = "1px solid red";

                           // um. time to reverse?


                           // do the reverse
                           var z = new CanvasRenderingContext2D(w, w);
                           z.drawImage(csrci, 0, 0, w, w);
                           z.canvas.AttachToDocument();

                           // whats the bytes?

                           var zbytes = z.bytes;

                           new IHTMLPre { 
                                new {
                                    zbytes.Length,
                        
                                    md5 = zbytes.ToMD5Bytes().ToHexString() ,
                                    u8 = new [] { 
                                        zbytes[0 * 4 + 0],
                                        zbytes[0 * 4 +1],
                                        zbytes[0 * 4 +2],
                                        zbytes[0 * 4 +3],

                                        zbytes[1 * 4 + 0],
                                        zbytes[1 * 4 +1],
                                        zbytes[1 * 4 +2],
                                        zbytes[1 * 4 +3]
                                    }.ToHexString() 
                                }
                            }.AttachToDocument();

                           // { Length = 8236900, md5 = 166c1b692fad548789a12a3ae5f0a7ae, u4 = 0000003c }

                           #region decode
                           var decodebytes = await Task.Factory.StartNew(
                               new { zbytes },
                               scope =>
                               {
                                   // Native.Console.WriteLine += ?

                                   // { Length = 2053956, u4 = 3c68746d } 

                                   Console.WriteLine(
                                    new
                                    {
                                        scope.zbytes.Length,

                                        u4 = new[] { 
                                            scope.zbytes[0 * 4 + 0],
                                            scope.zbytes[0 * 4 +1],
                                            scope.zbytes[0 * 4 +2],
                                            scope.zbytes[0 * 4 +3]
                                        }.ToHexString()
                                    }
                                   );


                                   // Uncaught Error: InvalidOperationException: { MethodToken = dAAABv_a4OTKgLfLC20SaJA } function is not available at { href =

                                   var wwbytes = new byte[scope.zbytes.Length / 4];
                                   var wi = 0;

                                   for (int i = 0; i < scope.zbytes.Length; i += 4)
                                   {
                                       // that be the red
                                       //wwbytes[wi] = scope.zbytes[i];

                                       // bet we need alpha
                                       wwbytes[wi] = scope.zbytes[i + 3];
                                       wi++;
                                   }



                                   return wwbytes;
                               }
                           );
                           #endregion

                           //{ Length = 8282884, md5 = ece6f7e935f0b424082445b273b8ed65, u4 = ff00003c }
                           //{ Length = 2070721, md5 = 47f7ec04a0b7cfc27e706583cc1a9bf7, u4 = 3c3c3c3c }

                           new IHTMLPre { 
                                new {
                                    decodebytes.Length,
                        
                                    md5 = decodebytes.ToMD5Bytes().ToHexString() ,
                                    u8 = new [] { 
                                        decodebytes[0 * 4 + 0],
                                        decodebytes[0 * 4 +1],
                                        decodebytes[0 * 4 +2],
                                        decodebytes[0 * 4 +3],

                                        decodebytes[1 * 4 + 0],
                                        decodebytes[1 * 4 +1],
                                        decodebytes[1 * 4 +2],
                                        decodebytes[1 * 4 +3]
                                    }.ToHexString() 
                                }
                            }.AttachToDocument();
                       }
                  );


               }
            );

        }