private static void Test2()
        {
            var container = "div".AttachToDocument();

            container.style.border = "1px solid red";
            container.style.width = "400px";
            container.style.height = "300px";
            container.style.display = IStyle.DisplayEnum.inline_block;

            var svg = new ISVGSVGElement();
            var layer = new ISVGGElement();

            var defs = new ISVGElementBase("defs");
            var radialGradient = new ISVGElementBase("radialGradient");

            radialGradient.id = "myRadGrad";
            radialGradient.setAttribute("r", "10%");
            radialGradient.setAttribute("spreadMethod", "reflect");

            var stop1 = new ISVGElementBase("stop");

            stop1.setAttribute("offset", "5%");
            stop1.setAttribute("stop-color", "red");
            stop1.setAttribute("stop-opacity", "0.8");

            radialGradient.appendChild(stop1);

            var stop2 = new ISVGElementBase("stop");

            stop2.setAttribute("offset", "95%");
            //stop2.setAttribute("stop-color", "blue");
            stop2.setAttribute("stop-opacity", "0.0");

            radialGradient.appendChild(stop2);

            defs.appendChild(radialGradient);

            var rect = new ISVGRectElement();

            rect.setAttribute("x", 0);
            rect.setAttribute("y", 0);
            rect.setAttribute("width", "100%");
            rect.setAttribute("height", "100%");
            rect.setAttribute("fill", "url(#myRadGrad)");

            layer.appendChild(defs, rect);
            svg.appendChild(layer);
            container.appendChild(svg);
        }
        /// <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)
        {
            page.svg.Orphanize();

            var svg = new ISVGSVGElement().AttachToDocument();
            var path = new ISVGPathElement().AttachTo(svg);

            path.setAttribute("style", "stroke: black; stroke-width: 4; fill: none;");

            path.d = "    M100,50  L10,10   L200,200   ";

            Native.Document.body.onmousemove +=
                e =>
                {
                    path.d += " L" + e.CursorX + "," + e.CursorY;

                };
        }
        private static void Test1()
        {
            var container = "div".AttachToDocument();

            container.style.border = "1px solid red";
            container.style.width = "400px";
            container.style.height = "300px";

            var svg = new ISVGSVGElement();
            var layer = new ISVGGElement();
            var text = new ISVGTextElement();
            var rect = new ISVGRectElement();

            rect.setAttribute("x", 70);
            rect.setAttribute("y", 20);
            rect.setAttribute("rx", 0);
            rect.setAttribute("ry", 0);
            rect.setAttribute("width", 160);
            rect.setAttribute("height", 160);
            rect.setAttribute("fill", "blue");

            text.setAttribute("x", "92");
            text.setAttribute("y", "32");
            text.setAttribute("fill", "red");
            //text.style.cursor = IStyle.CursorEnum.move;

            var img = new ISVGImageElement();


            img.href = new SimpleSVGexample.HTML.Images.FromAssets.TILE1436().src;

            img.setAttribute("x", 0);
            img.setAttribute("y", 0);
            img.setAttribute("width", 200);
            img.setAttribute("height", 200);
            // http://www.svgbasics.com/rotate.html
            img.setAttribute("transform", "rotate(-45 10 10)");

            var r = 0;


            (1000 / 20).AtInterval(
                delegate
                {
                    r++;

                    img.setAttribute("transform", "rotate(" + r + " 100 100)");

                }
            );

            var rectlayer = new ISVGGElement();

            rectlayer.appendChild(rect, text);
            //rectlayer.setAttribute("transform", "scale(0.5) translate(0, 0) rotate(45) skewX(20) skewY(5)");

            var tween = new TweenDataDouble();

            tween.Value = 1;
            tween.ValueChanged +=
                delegate
                {
                    rectlayer.setAttribute("opacity", tween.Value);

                };

            rectlayer.onmouseover +=
                delegate
                {
                    tween.Value = 0.5;

                };

            rectlayer.onmouseout +=
                delegate
                {
                    tween.Value = 1;

                };


            text.textContent = "hello world";


            layer.appendChild(rectlayer, img);
            svg.appendChild(layer);

            container.appendChild(svg);
        }
        public __Chart()
        {
            this.ChartAreas = new __ChartAreaCollection();
            this.Series = new __SeriesCollection();
            this.Legends = new __LegendCollection();

            // X:\jsc.svn\examples\javascript\svg\SVGChartExperiment\SVGChartExperiment\Application.cs

            this.InternalElement.style.overflow = DOM.IStyle.OverflowEnum.hidden;


            #region build something visible

            {
                var svg = new ISVGSVGElement
                {
                    //width = 200,
                    //height = 200
                };


                var polygon0 = new ISVGPolygonElement { }.AttachTo(svg);
                var polygon1 = new ISVGPolygonElement { }.AttachTo(svg);


                var SeriesOfInterest = new List<__Series>();

                var UpdateCounter = 0;

                Action update = delegate { };

                update = delegate
                {
                    UpdateCounter++;


                    Console.WriteLine("__Chart update " + new { UpdateCounter });



                    svg.width = this.clientWidth;
                    svg.height = this.clientHeight;

                    // width: 780px;

                    //svg.setAttribute("width", "200");

                    var w0 = new StringBuilder();
                    var w1 = new StringBuilder();



                    // for print!
                    var svghardmarginx = 16;
                    var svghardmarginy = 16;

                    #region add0
                    Action<double, double> add0 = (x, y) =>
                    {
                        var xx = (x * (this.clientWidth - 2 * svghardmarginx)) + svghardmarginx;
                        var yy = (y * (this.clientHeight - 2 * svghardmarginy)) + svghardmarginy;

                        w0.Append(xx + "," + yy + " ");

                    };

                    // the highlight
                    Action<double, double> add1 = (x, y) =>
                    {
                        var xx = (x * (this.clientWidth - 2 * svghardmarginx)) + svghardmarginx;
                        var yy = (y * (this.clientHeight - 2 * svghardmarginy)) + svghardmarginy;

                        w1.Append(xx + "," + yy + " ");

                    };
                    #endregion

                    //add0(1, 1);


                    // upside down

                    // databind?

                    //StackTrace
                    // jsc shall fill in the StackTrace info?

                    //Console.WriteLine(new { this.DataSource });

                    // 35:33486ms { DataSource = <Namespace>.BindingSource } 

                    // as IList instead?

                    // X:\jsc.svn\core\ScriptCoreLib\Shared\BCLImplementation\System\Data\DataTable.cs
                    var __DataSource = this.DataSource;
                    if (__DataSource != null)
                    {
                        // jsc as opertor for jsc does not like null yet?


                        var asIList = __DataSource as IList;
                        if (asIList == null)
                        {
                            Console.WriteLine("not IList " + new { __DataSource });
                            // 44:105945ms not IList

                            var asIListSource = __DataSource as IListSource;
                            if (asIListSource != null)
                            {
                                asIList = asIListSource.GetList();
                                Console.WriteLine("IListSource " + new { asIList });
                            }

                        }

                        var asBindingSource_Position = 0;
                        var asBindingSource = __DataSource as __BindingSource;
                        if (asBindingSource != null)
                        {
                            asBindingSource_Position = asBindingSource.Position;
                        }

                        //var asBindingSource = asIListSource.GetList();
                        if (asIList != null)
                        {
                            #region Series
                            foreach (Series s in this.Series)
                            {
                                var ss = (__Series)s;

                                // when the chart type changes, we may want to redraw our diagram.
                                // X:\jsc.svn\examples\javascript\forms\ChartTypeExperiment\ChartTypeExperiment\ApplicationControl.cs

                                // 44:95855ms { ChartType = 10, a
                                // 44:142897ms { ChartType = 13,






                                // hey SeriesOfInterest have we seen this series yet?
                                if (!SeriesOfInterest.Contains(ss))
                                {
                                    // okay. first time we see it.
                                    // lets start monitoring it for any changes we need to know about.

                                    ss.InternalChartTypeChanged += delegate
                                    {

                                        update();
                                    };

                                    SeriesOfInterest.Add(ss);
                                }



                                // 35:11741ms { asBindingSource = <Namespace>.BindingSource, Count = 5, XValueMember = Xvalues, YValueMembers = Series2 }

                                //item.XValueType
                                Console.WriteLine(new
                                {
                                    s.ChartType,

                                    asIList,
                                    asIList.Count,


                                    s.XValueMember,
                                    s.YValueMembers
                                });


                                Func<string, double> ConvertToDoubleOrZero = zz =>
                                {
                                    // http://stackoverflow.com/questions/586436/double-tryparse-or-convert-todouble-which-is-faster-and-safer

                                    if (string.IsNullOrEmpty(zz))
                                        return 0;


                                    return double.Parse(zz);
                                };




                                var datas =
                                    from rowIndex in Enumerable.Range(0, asIList.Count)

                                    let asDataRowView = (DataRowView)asIList[rowIndex]

                                    //let asDataRowView = asBindingSource[rowIndex] as DataRowView
                                    //where asDataRowView != null

                                    // Error: Invalid value for <polygon> attribute points="16,155 16,43.8 150.4,16 284.8,71.6 419.2,132.25454545454545 553.6,43.8 688,NaN 688,155 " 

                                    let XValueMember = asDataRowView[s.XValueMember]
                                    let YValueMembers = asDataRowView[s.YValueMembers]

                                    // try?
                                    //let x = Convert.ToDouble(XValueMember)
                                    //let y = Convert.ToDouble(YValueMembers)

                                    // new rows added, may show up empty!
                                    let y = ConvertToDoubleOrZero((string)YValueMembers)


                                    select new { rowIndex, XValueMember, y };


                                var data0 = datas.ToArray();

                                var data1 = datas.Take(asBindingSource_Position + 1).ToArray();

                                // what about neg values?
                                //var xmax = data.Max(z => z.x);
                                var ymax = data0.Max(z => z.y);

                                //Console.WriteLine(new { data0.Length, max = ymax });

                                // script: error JSC1000: No implementation found for this native method, please implement [static System.Convert.ToDouble(System.Object)]

                                //35:524ms { item = { rowIndex = 0, x = 1, y = 44 }, xx = 0.25, yy = 0.19999999999999996 }
                                //35:525ms { item = { rowIndex = 1, x = 2, y = 55 }, xx = 0.5, yy = 0 }
                                //35:525ms { item = { rowIndex = 2, x = 3, y = 33 }, xx = 0.75, yy = 0.4 }
                                //35:526ms { item = { rowIndex = 3, x = 4, y = 9 }, xx = 1, yy = 0.8363636363636364 }
                                //35:526ms { item = { rowIndex = 4, x = 5, y = 44 }, xx = 1.25, yy = 0.19999999999999996 }

                                //foreach (var item in data.OrderBy(z => z.x))




                                //44:3380ms { ChartType = 0, asIList = <Namespace>.BindingSource, Count = 5, XValueMember = Xvalues, YValueMembers = Series2 }
                                //44:11642ms __Chart update { UpdateCounter = 18 } view-source:38201
                                //44:11643ms { ChartType = 10, asIList = <Namespace>.BindingSource, Count = 5, XValueMember = Xvalues, YValueMembers = Series2 } view-source:38160
                                //44:16057ms __Chart update { UpdateCounter = 19 } view-source:38201
                                //44:16057ms { ChartType = 13, asIList = <Namespace>.BindingSource, Count = 5, XValueMember = Xvalues, YValueMembers = Series2 } 


                                // .1?
                                // 44:619ms { ColumnWidth = 315 }
                                var ColumnWidth =
                                    (1.0 / data0.Length) * 0.5;


                                if (ss.ChartType == SeriesChartType.Column)
                                {
                                    // changing constants, jsc should autoupdate currently running code in the browser.
                                    // should we have an int constant pool for that as we have for static strings?
                                    svghardmarginx =
                                        16 +
                                        (this.clientWidth / data0.Length) / 2;
                                }


                                //Console.WriteLine(
                                //    new { ColumnWidth }
                                //    );


                                add0(0, 1);

                                add1(0, 1);


                                // .net does not seem to auto reorder x axis values per default
                                foreach (var item0 in data0)
                                {
                                    //var xx = item.x / Math.Max(xmax, 1);
                                    //var xx = item.rowIndex / Math.Max(data.Length, 1);
                                    // fk int math.

                                    var xx = (double)item0.rowIndex / Math.Max(data0.Length - 1, 1);
                                    var yy = 1 - (item0.y / Math.Max(ymax, 1));

                                    if (ss.ChartType == SeriesChartType.Area)
                                    {
                                        //Console.WriteLine(new { item, xx, yy });

                                        add0(
                                            xx,
                                            yy
                                          );

                                    }
                                    else
                                    {
                                        // how do we draw column?


                                        //Console.WriteLine(new { item, xx, yy });

                                        add0(
                                           xx - ColumnWidth,
                                           1
                                         );

                                        add0(
                                           xx - ColumnWidth,
                                           yy
                                         );


                                        add0(
                                              xx + ColumnWidth,
                                              yy
                                            );

                                        add0(
                                           xx + ColumnWidth,
                                           1
                                         );

                                    }
                                }

                                foreach (var item1 in data1)
                                {
                                    var xx = (double)item1.rowIndex / Math.Max(data0.Length - 1, 1);
                                    var yy = 1 - (item1.y / Math.Max(ymax, 1));

                                    //Console.WriteLine(new { item1, xx, yy });

                                    add1(
                                        xx,
                                        yy
                                      );

                                    if (item1.rowIndex == asBindingSource_Position)
                                    {
                                        // this is the last selection item.


                                        this.InternalElement.title =
                                                item1.XValueMember + " " + item1.y;




                                        add1(
                                         xx,
                                         1.0
                                       );
                                    }
                                }

                                //35:704ms { rowIndex = 0, XValueMember = 1, YValueMembers = 44 }
                                //35:704ms { rowIndex = 1, XValueMember = 2, YValueMembers = 55 }
                                //35:705ms { rowIndex = 2, XValueMember = 3, YValueMembers = 33 }
                                //35:705ms { rowIndex = 3, XValueMember = 4, YValueMembers = 9 }
                                //35:705ms { rowIndex = 4, XValueMember = 5, YValueMembers = 44 }



                                //for (int i = 0; i < asBindingSource.Count; i++)
                                //{
                                //    add(
                                //        i / (asBindingSource.Count - 1),
                                //        i / (asBindingSource.Count - 1)
                                //        );

                                //}

                                // we can only talk to 1 for now
                                break;
                            }
                            #endregion


                            add0(1.0, 1.0);

                            polygon0.setAttribute("style", "fill:purple;stroke:darkpurple;stroke-width:1;");
                            polygon0.points = w0.ToString();

                            //polygon1.setAttribute("style", "fill:rgba(255,255,255,0.07);stroke:rgba(255,255,255,0.0);stroke-width:8;");
                            polygon1.setAttribute("style", "fill:rgba(255,255,255," + this.BindingSourcePositionAlpha + ");stroke:rgba(255,255,255,0.0);stroke-width:8;");
                            polygon1.points = w1.ToString();
                            return;
                        }
                    }






                    add0(0, 1);

                    add1(0, 1);


                    add0(0, 0.8);
                    add0(0.2, 0.2);
                    add0(0.4, 0.8);
                    add0(0.6, 0.6);
                    add0(0.8, 0.8);

                    add0(1.0, 1.0);

                    polygon0.setAttribute("style", "fill:red;stroke:darkpurple;stroke-width:1;");
                    polygon0.points = w0.ToString();
                };


                InternalDataSourceChanged += delegate
                {
                    #region jsc experience, not available for CLR
                    {
                        var asBindingSource = this.DataSource as __BindingSource;
                        if (asBindingSource != null)
                        {
                            asBindingSource.PositionChanged +=
                                delegate
                                {
                                    update();
                                };
                        }
                    }
                    #endregion
                };

                InternalAtDataBind += delegate
                {
                    update();
                };

                update();

                //this.ClientSizeChanged +=
                this.SizeChanged +=
                    delegate
                    {
                        update();
                    };




                svg.AttachTo(InternalElement);
            }

            #endregion
        }
        /// <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)
        {
            // http://www.w3schools.com/svg/svg_polygon.asp
            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140426


            //<svg height="210" width="500">
            //      <polygon points="200,10 250,190 160,210" style="fill:lime;stroke:purple;stroke-width:1" />
            //  </svg>


            //{
            //    var svg = new ISVGSVGElement { width = 200, height = 200 };

            //    var polygon = new ISVGElementBase("polygon")
            //    {

            //    }.AttachTo(svg);

            //    polygon.setAttribute("points", "200,10 250,190 160,210");
            //    polygon.setAttribute("style", "fill:lime;stroke:purple;stroke-width:1;");


            //    svg.AttachToDocument();
            //}



            {
                var svg = new ISVGSVGElement
                {
                    width = 200,
                    height = 200
                };
                // width: 780px;

                //svg.setAttribute("width", "200");

                var w = new StringBuilder();

                Action<double, double> add = (x, y) =>
                {
                    w.Append((x * 200.0) + "," + (y * 200.0) + " ");

                };

                add(1, 1);
                add(0, 1);

                add(0, 0.8);
                add(0.2, 1.0);
                add(0.4, 0.8);
                add(0.6, 0.6);
                add(0.8, 0.8);
                add(1.0, 0.0);

                var polygon = new ISVGPolygonElement
                {
                    //points = "200,10 250,190 160,210"
                    points = w.ToString()

                }.AttachTo(svg);

                polygon.setAttribute("style", "fill:lime;stroke:purple;stroke-width:1;");


                svg.AttachToDocument();

                // { polygon_style = fill:lime;stroke:purple;stroke-width:1; }
                var polygon_style = polygon.getAttribute("style");

                new IHTMLPre { 
                    new {polygon_style}
                }.AttachToDocument();
            }

        }
        /// <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)
        {
            // ! to convert svg to image we would need to normalize source, which defeats shadowdom purpose

            // X:\jsc.svn\examples\javascript\svg\SVGCSSContent\SVGCSSContent\Application.cs

            var s = new ISVGSVGElement
            {

            };

            var f = new ISVGForeignObject().AttachTo(s);
            //requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">

            //f.setAttribute("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility");

            // http://starkravingfinkle.org/blog/2007/07/firefox-3-svg-foreignobject/
            // http://stackoverflow.com/questions/11194403/svg-foreignobject-not-showing-in-chrome
            var div = new IHTMLDiv
            {
            };

            new IHTMLContent { select = "div" }.AttachTo(div);

            //var divbody = new IHTMLDiv
            //{
            //    innerHTML = "I like <span style='color:white; text-shadow:0 2px 2px blue;'>cheese</span>"
            //}.AttachTo(div);
            // https://groups.google.com/forum/#!topic/svg-edit/60HICxGWFNE
            // http://www.w3.org/TR/SVG11/extend.html#ForeignObjectElement

            // http://css.dzone.com/articles/securing-pixel-data-svg-and
            // view-source:http://starkravingfinkle.org/blog/wp-content/uploads/2007/07/foreignobject-transform.svg
            // http://stackoverflow.com/questions/6849192/what-can-be-rendered-in-foreignobject-element-when-svg-is-embedded-in-html5
            //new StockToolboxImageForWebGLComponent().AttachTo(divbody);

            //new Anonymous_LogosSingle().AttachTo(divbody);

            // for detatched calculations!
            //div.style.fontFamily = IStyle.FontFamilyEnum.Verdana;
            //div.style.fontSize = "40px";
            div.style.display = IStyle.DisplayEnum.inline_block;

            // div.AttachToDocument();

            s.width = 400;
            s.height = 100;

            //s.width = div.clientWidth;
            //s.height = div.clientHeight;
            //s.height = div.clientHeight;

            div.AttachTo(f);


            //s.AttachToDocument();
            s.AttachTo(Native.body.shadow);

            // and then show any canvases
            //new IHTMLContent { select = "canvas" }.AttachTo(div);

            
            // https://developer.mozilla.org/en-US/docs/Web/HTML/Canvas/Drawing_DOM_objects_into_a_canvas
            //var c = new CanvasRenderingContext2D(400, 100);

            //c.drawImage(
        }
        /// <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)
        {
            //ms InternalFieldsFromTypeInitializer view-source:35337
            //13ms GetInternalFields load fromlocalstorage!  view-source:35337
            //22ms IHTMLImage <- IHTMLDiv view-source:35337
            //23ms Task<ISVGSVGElement> <- IHTMLDiv view-source:35337
            //31ms ContinueWhenAll { Length = 1, scheduler = [object Object], ManagedThreadId = 1 } view-source:35337
            //32ms IHTMLImage <- Task<ISVGSVGElement> view-source:35337
            //32ms enter contentImage view-source:35337
            //Application Cache Progress event (2 of 3) http://192.168.1.200:16552/view-source 192.168.1.200/:1
            //Application Cache Progress event (3 of 3)  192.168.1.200/:1
            //Application Cache Cached event 192.168.1.200/:1
            //133ms ContinueWhenAll_yield { scheduler = [object Object] } view-source:35337
            //134ms { clientWidth = 679, clientHeight = 249 } view-source:35337
            //170ms yield contentImage view-source:35337
            //61247ms enter contentImage view-source:35337
            //61248ms yield contentImage view-source:35337

            page.body.css.before.contentImage = new Foo().AsNode();
            page.body.css.before.style.position = IStyle.PositionEnum.absolute;
            page.body.css.before.style.bottom = "0";

            var s = new ISVGSVGElement
            {

            };

            var f = new ISVGForeignObject().AttachTo(s);

            var fdiv = new IHTMLDiv().AttachTo(f);

            fdiv.style.fontFamily = IStyle.FontFamilyEnum.Verdana;

            // we need to serialize styles now
            // svg wont have any default html css styles at all
            fdiv.style.fontSize = "12px";

            var div = new Foo();

            var hidden = new IHTMLDiv { }.AttachTo(Native.document.documentElement);
            hidden.style.position = IStyle.PositionEnum.@fixed;
            hidden.style.visibility = IStyle.VisibilityEnum.hidden;
            //hidden.style.display = IStyle.DisplayEnum.none;

            div.PageContainer.style.display = IStyle.DisplayEnum.inline_block;
            div.AttachTo(hidden);

            new IHTMLButton { "do " + new { div.PageContainer.clientWidth, div.PageContainer.clientHeight } }.AttachToDocument().WhenClicked(
               async button =>
               {

                   //div.querySelectorAll("img").WithEach(
                   div.ImageElements().WithEach(
                       q =>
                       {
                           q.src = q.toDataURL();

                       }
                   );

                   button.Orphanize();
                   s.setAttribute("width", div.PageContainer.clientWidth + 0);
                   s.setAttribute("height", div.PageContainer.clientHeight + 0);
                   div.AttachTo(fdiv);

                   // Uncaught SecurityError: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
                   IHTMLImage i = s;
                   //Task<IHTMLCanvas> ic = s;

                   //var c = await ic;


                   //var ii = i.toDataURL();

                   page.body.css.after.contentImage = i;
                   page.body.css.after.style.position = IStyle.PositionEnum.absolute;
                   page.body.css.after.style.right = "0";

                   Console.WriteLine("cursor");
                   // cursor no longer appears?
                   Native.document.documentElement.style.cursorImage = i;
                   //Native.css.style.cursorImage = s;
                   Console.WriteLine("icon");
                   Native.document.icon = i;
               }
           );

        }
        /// <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)
        {

            //page.body.css.after.contentImage = new HTML.Images.FromAssets.Anonymous_LogosSingle();

            var s = new ISVGSVGElement
            {

            };

            var f = new ISVGForeignObject().AttachTo(s);
            //requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">

            //f.setAttribute("requiredFeatures", "http://www.w3.org/TR/SVG11/feature#Extensibility");

            // http://starkravingfinkle.org/blog/2007/07/firefox-3-svg-foreignobject/
            // http://stackoverflow.com/questions/11194403/svg-foreignobject-not-showing-in-chrome
            var div = new IHTMLDiv
            {
            };

            var divbody = new IHTMLDiv
            {
                innerHTML = "I like <span style='color:white; text-shadow:0 2px 2px blue;'>cheese</span>"
            }.AttachTo(div);
            // https://groups.google.com/forum/#!topic/svg-edit/60HICxGWFNE
            // http://www.w3.org/TR/SVG11/extend.html#ForeignObjectElement

            // http://css.dzone.com/articles/securing-pixel-data-svg-and
            // view-source:http://starkravingfinkle.org/blog/wp-content/uploads/2007/07/foreignobject-transform.svg
            // http://stackoverflow.com/questions/6849192/what-can-be-rendered-in-foreignobject-element-when-svg-is-embedded-in-html5
            new StockToolboxImageForWebGLComponent().AttachTo(divbody);

            new Anonymous_LogosSingle().AttachTo(divbody);

            div.style.fontFamily = IStyle.FontFamilyEnum.Verdana;
            div.style.fontSize = "40px";
            div.style.display = IStyle.DisplayEnum.inline_block;

            div.AttachToDocument();

            //page.body.css.before.content = new { div.clientWidth, div.clientHeight }.ToString();



            #region do
            new IHTMLButton { "do" }.AttachToDocument().WhenClicked(
                button =>
                {
                    //div.querySelectorAll("img").WithEach(
                    div.ImageElements().WithEach(
                        q =>
                        {
                            q.src = q.toDataURL();

                        }
                    );

                    button.Orphanize();

                    //s.width
                    //s.setAttribute("width", div.clientWidth + 0);
                    //s.setAttribute("height", div.clientHeight + 0);

                    s.width = div.clientWidth;
                    s.height = div.clientHeight;

                    div.AttachTo(f);


                    //page.body.css.before.content = xmlstring;




                    // var data =
                    //"<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
                    //  "<foreignObject width='100%' height='100%'>" +
                    //    "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                    //      "<em>I</em> like <span style='color:white; text-shadow:0 0 2px blue;'>cheese</span>" +
                    //    "</div>" +
                    //  "</foreignObject>" +
                    //"</svg>";

                    //                    var ss = @"<svg xmlns='http://www.w3.org/2000/svg' width='600' height='200'>
                    //<foreignObject width='100%' height='100%'>
                    //<HTML xmlns='http://www.w3.org/1999/xhtml'>
                    //<BODY style=' font-size: 30px;'>
                    //This is <span style='color: green'>HTML</span>.
                    //An img: <img src='data:image/png;base64,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'/>
                    //
                    //
                    //</BODY>
                    //</HTML>
                    //</foreignObject></svg>";



                    //var img = new IHTMLImage();
                    ////var url = "data:image/svg+xml;base64," + Convert.ToBase64String(Encoding.UTF8.GetBytes(s.AsXElement().ToString()));
                    //var url = "data:image/svg+xml;base64," + Convert.ToBase64String(Encoding.UTF8.GetBytes(xmlstring));
                    ////var url = "data:image/svg+xml;base64," + Convert.ToBase64String(Encoding.UTF8.GetBytes(ss));
                    //img.src = url;

                    //img.InvokeOnComplete(
                    //    delegate
                    //    {
                    //        page.body.css.after.contentImage = img;
                    //        page.body.css.after.style.border = "1px solid red";

                    //    }
                    //);

                    page.body.css.after.contentImage = s;
                    //page.body.css.after.style.border = "1px solid red";

                }
            );
            #endregion


        }
        /// <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)
        {
            var random = new Random();
            device_id = random.Next();

            #region con
            var con = new ConsoleForm();

            con.InitializeConsoleFormWriter();
            con.StartPosition = FormStartPosition.Manual;
            con.Show();

            // make it slim
            con.Height = 100;

            // TopMost
            con.GetHTMLTarget().style.zIndex = 20002;
            con.Opacity = 0.9;




            Action Toggle =
                delegate
                {
                    if (con.WindowState == FormWindowState.Minimized)
                    {
                        con.WindowState = FormWindowState.Normal;

                    }
                    else
                    {
                        con.WindowState = FormWindowState.Minimized;


                    }

                    // put the console far right bottom
                    con.MoveTo(
                        Native.window.Width - con.Width,
                        Native.window.Height - con.Height
                    );

                };

            Action<int> AtKeyCode =
               KeyCode =>
               {
                   Console.WriteLine(
                       new { KeyCode }

                   );



                   // US
                   if (KeyCode == 222)
                   {
                       Toggle();
                   }
                   // EE
                   if (KeyCode == 192)
                   {
                       Toggle();
                   }
               };


#if onorientationchange
            Native.window.onorientationchange +=
                e =>
                {
                    Toggle();
                };
#endif

            Native.document.onkeyup +=
                e =>
                {
                    AtKeyCode(e.KeyCode);

                };

            Toggle();
            #endregion

            Console.WriteLine("console ready for " + new { id = device_id });

            var x = 0;
            var y = 0;

            #region Virtual Screen
            FormStyler.AtFormCreated = LikeDesktop;
            var fs = new Form { };

            //fs.FormBorderStyle = FormBorderStyle.None;

            fs.BackColor = Color.FromArgb(0, 148, 155);
            fs.Width = Native.screen.width / 4;
            fs.Height = Native.screen.height / 4;
            fs.Show();
            fs.Opacity = 0.5;

            FormStyler.AtFormCreated = LikeVirtualScreen;
            var fvs = new Form { Text = "Virtual Screen" };
            fvs.BackColor = Color.Transparent;
            FormStyler.AtFormCreated = FormStyler.LikeWindowsClassic;
            fvs.Width = Native.screen.width / 4;
            fvs.Height = Native.screen.height / 4;
            fvs.Show();
            fvs.Owner = fs;

            var fw = new Form { };

            fw.Width = Native.window.Width / 4;
            fw.Height = Native.window.Height / 4;
            fw.Show();
            fw.Owner = fvs;
            fw.Opacity = 0.8;

            KeepOwnedFormsLinkedToOwnerLocation(fs);
            KeepOwnedFormsLinkedToOwnerLocation(fvs);
            KeepOwnedFormsLinkedToOwnerLocation(fw);
            #endregion


            // doesnt work yet?
            //fw.SizeGripStyle = SizeGripStyle.Hide;

            var svg = new ISVGSVGElement().AttachTo(page.content);
            svg.style.SetLocation(0, 0);

            var vsvg = new ISVGSVGElement().AttachTo(fvs.GetHTMLTarget());
            vsvg.style.SetLocation(0, 0);

            #region VirtualScreenUpdate
            Action VirtualScreenUpdate = delegate
            {
                if (fs.Capture)
                    return;

                // dragging it?
                if (fvs.Capture)
                    return;

                var max_right = fvs.OwnedForms.Max(k => k.Right);
                var min_left = fvs.OwnedForms.Min(k => k.Left);

                var max_bottom = fvs.OwnedForms.Max(k => k.Bottom);
                var min_top = fvs.OwnedForms.Min(k => k.Top);

                DisableKeepOwnedFormsLinkedToOwnerLocation = true;

                fvs.Left = min_left;
                fvs.Top = min_top;
                fvs.Width = max_right - min_left;
                fvs.Height = max_bottom - min_top;

                page.content.style.SetLocation(
                    (min_left - fw.Left) * 4,
                    (min_top - fw.Top) * 4,
                    (max_right - min_left) * 4,
                    (max_bottom - min_top) * 4
                );



                DisableKeepOwnedFormsLinkedToOwnerLocation = false;

            };
            #endregion


            fw.LocationChanged +=
                delegate
                {
                    VirtualScreenUpdate();
                };

            #region AtResize
            Action AtResize = delegate
            {
                // screen can change, but only once, when window is moved to the other monitor?
                fs.Text = "Screen " + new { Native.screen.width, Native.screen.height };
                fs.Width = Native.screen.width / 4;
                fs.Height = Native.screen.height / 4;

                fw.Text = " " + new { Native.window.Width, Native.window.Height
#if onorientationchange                    
                    , Native.window.orientation 
#endif
                };
                fw.Width = Native.window.Width / 4;
                fw.Height = Native.window.Height / 4;

                VirtualScreenUpdate();
            };



            Native.window.onresize +=
                delegate
                {
                    AtResize();
                };

            Native.window.onfocus +=
                delegate
                {
                    AtResize();
                };

            Native.window.onblur +=
                delegate
                {
                    AtResize();
                };

            new ScriptCoreLib.JavaScript.Runtime.Timer(
                delegate
                {
                    AtResize();
                }
            ).StartInterval(1000 / 2);
            #endregion


            // what is attaching what?
            // what about await
            var svgcursor1ghost = new cursor1().AttachTo(page.content).ToSVG();

            var svgcursor1 = new cursor1().AttachTo(page.content).ToSVG();

            svgcursor1.fill += svgcursor1ghost.fill;

            var vcursor = new cursor1().AttachTo(fvs.GetHTMLTarget()).ToSVG();

            var Shadows = new List<Form>();

            Func<Form, Form> CreateShadow =
                _fw =>
                {
                    FormStyler.AtFormCreated = LikeVirtualWindow;
                    var fwshadow = new Form();
                    Shadows.Add(fwshadow);

                    fwshadow.BackColor = Color.Transparent;
                    FormStyler.AtFormCreated = FormStyler.LikeWindowsClassic;
                    fwshadow.Width = Native.screen.width / 4;
                    fwshadow.Height = Native.screen.height / 4;
                    fwshadow.Show();


                    Action fwshadow_update = delegate
                    {

                        fwshadow.MoveTo(_fw.Left, _fw.Top);
                        fwshadow.SizeTo(_fw.Width, _fw.Height);
                    };

                    _fw.LocationChanged +=
                        delegate
                        {
                            fwshadow_update();
                        };

                    _fw.SizeChanged +=
                        delegate
                        {
                            fwshadow_update();

                        };

                    fwshadow_update();

                    _fw.BringToFront();

                    return fwshadow;
                };

            Shadows.Add(CreateShadow(fw));

            bool canexit = false;
            bool canenter = true;

            Action at_exit_MultiMouseMode = delegate
            {
                //Console.WriteLine("at_exit_MultiMouseMode");
            };

            Action at_enter_MultiMouseMode = delegate
            {

                //Console.WriteLine("at_enter_MultiMouseMode");
            };

            Action<IEvent.MouseButtonEnum> at_mousedown = button =>
            {

                //Console.WriteLine("at_enter_mousedown: " + button);
            };


            Action at_mouseup = delegate
            {

                //Console.WriteLine("at_enter_mouseup");
            };




            var path = new ISVGPathElement().AttachTo(svg);
            path.setAttribute("style", "stroke: black; stroke-width: 4; fill: none;");

            var path_d = "";



            var vpath = new ISVGPathElement().AttachTo(vsvg);
            vpath.setAttribute("style", "stroke: black; stroke-width: 1; fill: none;");

            var vpath_d = "";

            bool internal_ismousedown = false;

            Action<IEvent.MouseButtonEnum> internal_mousedown = button =>
            {
                internal_ismousedown = true;

                path = new ISVGPathElement().AttachTo(svg);

                if (button == IEvent.MouseButtonEnum.Left)
                    path.setAttribute("style", "stroke: black; stroke-width: 4; fill: none;");
                else
                    path.setAttribute("style", "stroke: rgb(0, 108, 115); stroke-width: 32; fill: none;");

                path_d = "";


                vpath = new ISVGPathElement().AttachTo(vsvg);

                if (button == IEvent.MouseButtonEnum.Left)
                    vpath.setAttribute("style", "stroke: black; stroke-width: 1; fill: none;");
                else
                    vpath.setAttribute("style", "stroke: rgb(0, 108, 115); stroke-width: 8; fill: none;");

                vpath_d = "";

                svgcursor1.fill(0, 0, 255);
                vcursor.fill(0, 0, 255);

                //path.d = "    M100,50  L10,10   L200,200   ";
                path_d += " M" + x + "," + y;
                path.d = path_d;

                vpath_d += " M" + (x / 4) + "," + (y / 4);
                vpath.d = vpath_d;
            };

            Action<IEvent.MouseButtonEnum> mousedown = button =>
            {
                at_mousedown(button);
                internal_mousedown(button);
            };

            Action internal_mouseup = delegate
            {
                internal_ismousedown = false;





                svgcursor1.fill(0, 255, 0);
                vcursor.fill(0, 255, 0);
            };

            Action mouseup = delegate
            {
                at_mouseup();
                internal_mouseup();
            };



            #region exit_MultiMouseMode
            Action internal_exit_MultiMouseMode = delegate
            {
                svgcursor1.fill(0, 0, 0);
                vcursor.fill(0, 0, 0);

                con.Opacity = 0.9;
                page.content.style.Opacity = 0.3;
                page.content.style.zIndex = 0;

                page.content.style.backgroundColor = "rgba(0, 148, 155, 1)";
                Native.Document.body.style.backgroundColor = "black";

                page.content.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "blur(3px)";
                    }
                );

                page.info.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "";
                    }
                );

                Shadows.WithEach(
                   f =>
                       f.GetHTMLTarget().style.With(
                           (dynamic s) =>
                           {
                               s.webkitFilter = "";
                           }
                       )
                 );


                fs.FormsByOwnership().WithEach(
                 f =>
                     f.GetHTMLTarget().style.With(
                         (dynamic s) =>
                         {
                             s.webkitFilter = "";

                         }
                     )
            );


                fvs.OwnedForms.WithEach(
                    k =>
                    {
                        k.GetHTMLTarget().style.display = IStyle.DisplayEnum.block;
                    }
                );




            };

            Action exit_MultiMouseMode = delegate
            {
                if (!canexit)
                    return;

                canexit = false;
                canenter = true;

                at_exit_MultiMouseMode();
                internal_exit_MultiMouseMode();
            };
            #endregion

            #region enter_MultiMouseMode
            Action internal_enter_MultiMouseMode = delegate
            {
                svgcursor1.fill(255, 0, 0);
                vcursor.fill(255, 0, 0);
                con.Opacity = 0.5;

                page.content.style.Opacity = 1.0;
                page.content.style.backgroundColor = "";
                Native.Document.body.style.backgroundColor = "rgba(0, 148, 155, 1)";

                page.content.style.zIndex = 20000;
                con.GetHTMLTarget().style.zIndex = 20002;
                page.content.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "";
                    }
                );

                page.info.style.With(
                    (dynamic s) =>
                    {
                        s.webkitFilter = "blur(3px)";
                    }
                );


                fvs.OwnedForms.WithEach(
                     k =>
                     {
                         k.GetHTMLTarget().style.display = IStyle.DisplayEnum.none;
                     }
                 );

                Shadows.WithEach(
                  f =>
                      f.GetHTMLTarget().style.With(
                          (dynamic s) =>
                          {
                              s.webkitFilter = "blur(3px)";
                          }
                      )
                );


                fs.FormsByOwnership().WithEach(
                    f =>
                        f.GetHTMLTarget().style.With(
                            (dynamic s) =>
                            {
                                s.webkitFilter = "blur(3px)";
                            }
                        )
                );
            };

            Action enter_MultiMouseMode = delegate
            {
                if (!canenter)
                    return;

                canexit = true;
                canenter = false;

                at_enter_MultiMouseMode();
                internal_enter_MultiMouseMode();
            };
            #endregion





            #region onmousemove



            Native.Document.body.onmouseup +=
              e =>
              {
                  if (Native.Document.pointerLockElement == Native.Document.body)
                  {
                      mouseup();
                      return;
                  }
              };

            Native.Document.body.onmousedown +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        mousedown(e.MouseButton);
                        return;
                    }

                    Console.WriteLine("requesting MultiMouse mode!");

                    x = e.CursorX;
                    y = e.CursorY;
                    e.preventDefault();
                    Native.Document.body.requestPointerLock();

                };

            Action<int, int> at_set_cursor_position = delegate { };


            var pxx = 0;
            var pyy = 0;

            var ghost_busy = false;

            Action<int, int> internal_set_cursor_position =
                 (xx, yy) =>
                 {
                     // already set to that exact location!
                     if (pxx == xx)
                         if (pyy == yy)
                             return;


                     pxx = xx;
                     pyy = yy;

                     vcursor.Element.style.SetSize(
                           cursor1.ImageDefaultWidth / 4,
                           cursor1.ImageDefaultHeight / 4
                       );

                     vcursor.Element.style.SetLocation(
                           (xx - 14) / 4,
                           (yy - (64 - 56)) / 4
                       );


                     svgcursor1.Element.style.SetLocation(

                         xx - 14,

                         // inscaope/svg Y is upside down!
                         yy - (64 - 56)

                     );

                     if (!ghost_busy)
                     {
                         ghost_busy = true;

                         svgcursor1ghost.Element.style.Opacity = 0.2;
                         svgcursor1ghost.Element.style.With(
                                (dynamic s) => s.webkitTransition = "all 0.5s linear"
                         );

                         svgcursor1ghost.Element.style.SetLocation(

                            pxx - 14,

                            // inscaope/svg Y is upside down!
                            pyy - (64 - 56)

                        );

                         new ScriptCoreLib.JavaScript.Runtime.Timer(
                             delegate
                             {
                                 svgcursor1ghost.Element.style.SetLocation(

                                    pxx - 14,

                                    // inscaope/svg Y is upside down!
                                    pyy - (64 - 56)

                                );

                                 ghost_busy = false;
                             }
                         ).StartTimeout(500);
                     }


                     // if this window will be activated next time we can continue where we were
                     // told to..
                     x = xx;
                     y = yy;

                     if (internal_ismousedown)
                     {
                         path_d += " L" + x + "," + y;
                         path.d = path_d;

                         vpath_d += " L" + (x / 4) + "," + (y / 4);
                         vpath.d = vpath_d;
                     }

                 };

            Action<int, int> set_cursor_position =
                (xx, yy) =>
                {
                    at_set_cursor_position(xx, yy);
                    internal_set_cursor_position(xx, yy);
                };

            Native.Document.body.onmousemove +=
                e =>
                {
                    if (Native.Document.pointerLockElement == Native.Document.body)
                    {
                        enter_MultiMouseMode();

                        x += e.movementX;
                        y += e.movementY;

                        // clip it
                        // fullscreen behaves differently?
                        x = x.Min(fvs.Width * 4).Max(0);
                        y = y.Min(fvs.Height * 4).Max(0);

                        set_cursor_position(x, y);
                    }
                    else
                    {
                        exit_MultiMouseMode();
                    }

                };
            #endregion

            internal_exit_MultiMouseMode();
            internal_set_cursor_position(0, 0);

            Native.document.body.ontouchstart +=
                 e =>
                 {
                     e.preventDefault();
                     e.stopPropagation();

                     e.touches[0].With(
                         touch =>
                         {
                             // how do we enter?
                             enter_MultiMouseMode();
                             // exit by broswer history move?

                             set_cursor_position(touch.clientX, touch.clientY);

                             // ipad has 11 touchpoints. multiply that with the number of devices/
                             // for now we support 1 pointer per session :)

                             if (e.touches.length == 1)
                                 mousedown(IEvent.MouseButtonEnum.Left);
                             else
                                 mousedown(IEvent.MouseButtonEnum.Right);

                         }
                     );
                 };

            Native.document.body.ontouchend +=
               e =>
               {

                   e.preventDefault();
                   e.stopPropagation();



                   // ipad has 11 touchpoints. multiply that with the number of devices/
                   // for now we support 1 pointer per session :)

                   if (e.touches.length == 0)
                       mouseup();
                   else
                       mousedown(IEvent.MouseButtonEnum.Left);

               };

            Native.document.body.ontouchmove +=
                 e =>
                 {
                     e.preventDefault();
                     e.stopPropagation();


                     e.touches[0].With(
                         touch =>
                         {
                             set_cursor_position(touch.clientX, touch.clientY);
                         }
                     );
                 };



            #region onmessage

            bool disable_bind_reconfigure = false;


            Action<int, int> internal_reconfigure =
                delegate { };

            Action<MessageEvent, XElement> internal_onmessage =
                (e, xml) =>
                {
                    device_onmessage(0, xml);
                };

            Native.window.onmessage +=
                e =>
                {
                    // who sent this? :P
                    var source = (string)e.data;
                    //var now = DateTime.Now;
                    //Console.WriteLine(now + " " + source);


                    var xml = XElement.Parse(source);




                    internal_onmessage(e, xml);
                };

            var friendly_devices = new
            {
                source_device_id = 0,
                f = default(Form),
                children = new
                {
                    child_id = 0,
                    fc = default(Form)
                }.ToEmptyList()
            }.ToEmptyList();

            #region device_onmessage
            this.device_onmessage =
                (source_device_id, xml) =>
                {
                    // mothership to local network?
                    // source_device_id = 0 means it came from one of our virtual screens?

                    if (xml.Name.LocalName == "at_mousedown")
                    {
                        int button = int.Parse(xml.Attribute("button").Value);
                        internal_mousedown((IEvent.MouseButtonEnum)button);
                    }

                    if (xml.Name.LocalName == "at_mouseup")
                    {
                        internal_mouseup();
                    }

                    if (xml.Name.LocalName == "at_enter_MultiMouseMode")
                    {
                        internal_enter_MultiMouseMode();
                    }

                    if (xml.Name.LocalName == "at_exit_MultiMouseMode")
                    {
                        internal_exit_MultiMouseMode();
                    }

                    if (xml.Name.LocalName == "at_set_cursor_position")
                    {
                        int xx = int.Parse(xml.Attribute("x").Value);
                        int yy = int.Parse(xml.Attribute("y").Value);

                        internal_set_cursor_position(xx, yy);
                    }


                };
            #endregion

            var ListOfChildren = new { child_id = 0, fc = default(Form) }.ToEmptyList();

            // when is this called?
            this.device_bind =
                (mothership_postXElement) =>
                {
                    // we might now be able to invoke the server, and via that any other device
                    Console.WriteLine("device_bind");

                    #region at_enter_MultiMouseMode
                    at_enter_MultiMouseMode +=
                        delegate
                        {
                            var xml = new XElement("at_enter_MultiMouseMode");

                            mothership_postXElement(xml);
                        };
                    #endregion

                    #region at_exit_MultiMouseMode
                    at_exit_MultiMouseMode +=
                        delegate
                        {
                            mothership_postXElement(new XElement("at_exit_MultiMouseMode"));
                        };
                    #endregion

                    #region at_mousedown
                    at_mousedown +=
                      button =>
                      {
                          mothership_postXElement(new XElement("at_mousedown", new XAttribute("button", "" + (int)button)));
                      };
                    #endregion

                    #region at_mouseup
                    at_mouseup +=
                     delegate
                     {
                         mothership_postXElement(new XElement("at_mouseup"));
                     };
                    #endregion

                    #region at_set_cursor_position
                    at_set_cursor_position +=
                       (xx, yy) =>
                       {

                           var xml = new XElement("at_set_cursor_position",
                               // int not yet supported?
                                   new XAttribute("x", "" + xx),
                                   new XAttribute("y", "" + yy)
                               );

                           mothership_postXElement(
                               xml
                           );



                       };
                    #endregion

                    // now we can reply..
                    this.device_onmessage +=
                       (source_device_id, xml) =>
                       {
                           #region at_virtualwindowsync_reconfigure
                           if (source_device_id != 0)
                               if (xml.Name.LocalName == "at_virtualwindowsync_reconfigure")
                               {
                                   int __device_id = int.Parse(xml.Attribute("device_id").Value);

                                   if (__device_id == device_id)
                                   {
                                       // are we being reconfigured?

                                       friendly_devices.Where(k => k.source_device_id == source_device_id).WithEach(
                                           q =>
                                           {
                                               int dx = int.Parse(xml.Attribute("dx").Value);
                                               int dy = int.Parse(xml.Attribute("dy").Value);
                                               disable_bind_reconfigure = true;

                                               q.f.MoveTo(
                                                   fw.Left - dx,
                                                   fw.Top - dy
                                               );
                                               disable_bind_reconfigure = false;

                                           }
                                       );
                                   }
                               }
                           #endregion

                           #region at_virtualwindowsync
                           if (source_device_id != 0)
                               if (xml.Name.LocalName == "at_virtualwindowsync")
                               {
                                   Console.WriteLine("got at_virtualwindowsync");

                                   // do we know this device?
                                   var q = friendly_devices.FirstOrDefault(k => k.source_device_id == source_device_id);

                                   int w = int.Parse(xml.Attribute("w").Value);
                                   int h = int.Parse(xml.Attribute("h").Value);

                                   Action reposition = delegate { };

                                   if (q == null)
                                   {
                                       var fc = new Form { Text = new { source_device_id }.ToString() };

                                       q = new { source_device_id, f = fc, children = new { child_id = 0, fc = default(Form) }.ToEmptyList() };

                                       friendly_devices.Add(q);

                                       q.f.StartPosition = FormStartPosition.Manual;
                                       q.f.Show();
                                       // show should respect opacity?
                                       q.f.Opacity = 0.3;


                                       // where to put it?
                                       // left or right?

                                       var max_right = fvs.OwnedForms.Max(k => k.Right);
                                       var min_left = fvs.OwnedForms.Min(k => k.Left);

                                       if (source_device_id < device_id)
                                           q.f.Left = min_left - w;
                                       else
                                           q.f.Left = max_right;

                                       q.f.Top = fw.Top;
                                       q.f.Owner = fvs;

                                       var fcShadow = CreateShadow(q.f);
                                       Shadows.Add(fcShadow);

                                       #region from now on if we move any of our screens
                                       // in relation to this source_device_id we have to notify it

                                       Action SendDelta = delegate
                                       {
                                           var pdx = fc.Left - fw.Left;
                                           var pdy = fc.Top - fw.Top;

                                           mothership_postXElement(
                                             new XElement("at_virtualwindowsync_reconfigure",
                                                 new XAttribute("device_id", "" + source_device_id),
                                                 new XAttribute("dx", "" + pdx),
                                                 new XAttribute("dy", "" + pdy)
                                             )
                                           );
                                       };

                                       fw.LocationChanged +=
                                           delegate
                                           {
                                               if (disable_bind_reconfigure)
                                                   return;

                                               SendDelta();
                                           };

                                       fc.LocationChanged +=
                                           delegate
                                           {
                                               if (disable_bind_reconfigure)
                                                   return;


                                               SendDelta();
                                           };


                                       #endregion


                                   }

                                   // thanks for letting us know that you changed your size...
                                   q.f.Width = w;
                                   q.f.Height = h;


                                   xml.Elements("child").WithEach(
                                       cxml =>
                                       {
                                           // any new children?
                                           int child_id = int.Parse(cxml.Attribute("child_id").Value);

                                           int pdx = int.Parse(cxml.Attribute("pdx").Value);
                                           int pdy = int.Parse(cxml.Attribute("pdy").Value);

                                           int cw = int.Parse(cxml.Attribute("w").Value);
                                           int ch = int.Parse(cxml.Attribute("h").Value);

                                           var cq = q.children.FirstOrDefault(k => k.child_id == child_id);

                                           if (cq == null)
                                           {
                                               var fc = new Form { Text = new { source_device_id, child_id }.ToString() };

                                               cq = new { child_id, fc };

                                               q.children.Add(cq);

                                               cq.fc.StartPosition = FormStartPosition.Manual;
                                               cq.fc.Show();
                                               // show should respect opacity?
                                               cq.fc.Opacity = 0.2;

                                               // if this child needs to be between then add it
                                               // before reposition

                                               cq.fc.Owner = fvs;

                                               var fcShadow = CreateShadow(cq.fc);
                                               Shadows.Add(fcShadow);

                                           }


                                           cq.fc.Left = q.f.Left + pdx;
                                           cq.fc.Top = q.f.Top + pdy;

                                           // thanks for letting us know that you changed your size...
                                           cq.fc.Width = cw;
                                           cq.fc.Height = ch;
                                       }
                                   );

                               }
                           #endregion

                       };

                    // lets tell the world about virtual screens owned by us.
                    // lets start by advertising our size.

                    #region at_virtualwindowsync
                    var t = new ScriptCoreLib.JavaScript.Runtime.Timer(
                        delegate
                        {
                            // do we know whats the dx to other windows?
                            var xml = new XElement("at_virtualwindowsync",
                                // int not yet supported?
                                new XAttribute("w", "" + fw.Width),
                                new XAttribute("h", "" + fw.Height)


                            );

                            #region what about children?
                            ListOfChildren.WithEach(
                                c =>
                                {
                                    var pdx = c.fc.Left - fw.Left;
                                    var pdy = c.fc.Top - fw.Top;

                                    xml.Add(

                                        new XElement("child",
                                            new XAttribute("child_id", "" + c.child_id),
                                        // int not yet supported?
                                            new XAttribute("pdx", "" + pdx),
                                            new XAttribute("pdy", "" + pdy),
                                            new XAttribute("w", "" + c.fc.Width),
                                            new XAttribute("h", "" + c.fc.Height)
                                        )

                                    );
                                }
                            );
                            #endregion


                            mothership_postXElement(
                              xml
                            );

                            Console.WriteLine("sent at_virtualwindowsync");

                        }
                    );

                    t.StartInterval(5000);
                    #endregion

                };

            Action<IWindow, Form> bind =
                (w, fc) =>
                {
                    this.device_bind(w.postXElement);

                    internal_onmessage +=
                        (e, xml) =>
                        {
                            if (xml.Name.LocalName == "reconfigure")
                            {
                                // how do we know this reconfigrue event is for us?

                                if (e.source == w)
                                {
                                    disable_bind_reconfigure = true;

                                    int dx = int.Parse(xml.Attribute("dx").Value);
                                    int dy = int.Parse(xml.Attribute("dy").Value);

                                    //Console.WriteLine("reconfigure " + new { dx, dy, fw.Left });

                                    //fw.Left += dx;
                                    //fw.Top += dy;


                                    fc.MoveTo(
                                        fw.Left - dx,
                                        fw.Top - dy
                                    );

                                    disable_bind_reconfigure = false;
                                }
                            }
                        };

                    Action SendDelta = delegate
                    {
                        var pdx = fc.Left - fw.Left;
                        var pdy = fc.Top - fw.Top;

                        w.postXElement(
                          new XElement("reconfigure",
                              new XAttribute("dx", "" + pdx),
                              new XAttribute("dy", "" + pdy)
                          )
                        );
                    };

                    fw.LocationChanged +=
                        delegate
                        {
                            if (disable_bind_reconfigure)
                                return;

                            SendDelta();
                        };

                    fc.LocationChanged +=
                        delegate
                        {
                            if (disable_bind_reconfigure)
                                return;


                            SendDelta();
                        };
                };
            #endregion


            #region opener
            Native.window.opener.With(
                w =>
                {
                    // disable features
                    page.info.Hide();

                    Console.WriteLine("we have opener: " + w.document.location.href);

                    var fc = new Form { Text = "opener" };

                    fc.Owner = fvs;

                    Action cAtResize = delegate
                    {
                        fc.Text = "Opener " + new { w.Width, w.Height };
                        fc.Width = w.Width / 4;
                        fc.Height = w.Height / 4;
                    };

                    w.onresize += delegate
                    {
                        cAtResize();
                    };

                    var ct = new ScriptCoreLib.JavaScript.Runtime.Timer(
                       delegate
                       {
                           cAtResize();
                       }
                    );

                    ct.StartInterval(1000 / 15);

                    cAtResize();

                    fc.StartPosition = FormStartPosition.Manual;
                    fc.Show();
                    fc.Opacity = 0.7;
                    fc.BackColor = Color.Transparent;

                    var fcShadow = CreateShadow(fc);
                    Shadows.Add(fcShadow);



                    Native.window.requestAnimationFrame +=
                        delegate
                        {
                            // ScriptCoreLib Windows Forms has a few bugs:P
                            fc.MoveTo(fw.Left - fc.Width, fw.Top);

                            bind(w, fc);
                        };

                }
            );
            #endregion

            #region make info clickable

            page.info.onmousedown +=
             e =>
             {
                 if (internal_ismousedown)
                     return;

                 e.stopPropagation();
             };

            page.info.ontouchstart +=
              e =>
              {
                  if (internal_ismousedown)
                      return;


                  e.stopPropagation();
              };

            page.info.ontouchmove +=
          e =>
          {
              if (internal_ismousedown)
                  return;


              e.stopPropagation();
          };

            page.info.ontouchend +=
     e =>
     {
         if (internal_ismousedown)
             return;

         e.stopPropagation();
     };
            #endregion

            #region OpenChildSession



            page.OpenChildSession.onclick +=
                e =>
                {
                    e.preventDefault();

                    Console.WriteLine("open child session...");

                    Native.window.open(
                        Native.Document.location.href,
                        "_blank", 400, 400, true).With(
                        w =>
                        {
                            w.onload +=
                                delegate
                                {
                                    if (w.document.location.href == "about:blank")
                                        return;

                                    Console.WriteLine("child onload " + w.document.location.href);

                                    var fc = new Form { Text = "child" };



                                    Action cAtResize = delegate
                                    {
                                        fc.Text = "Child " + new { w.Width, w.Height };
                                        fc.Width = w.Width / 4;
                                        fc.Height = w.Height / 4;

                                        VirtualScreenUpdate();
                                    };

                                    w.onresize += delegate
                                    {
                                        cAtResize();

                                    };

                                    var ct = new ScriptCoreLib.JavaScript.Runtime.Timer(
                                       delegate
                                       {
                                           cAtResize();
                                       }
                                    );

                                    ct.StartInterval(1000 / 2);

                                    //cAtResize();

                                    fc.StartPosition = FormStartPosition.Manual;
                                    fc.Show();
                                    fc.Opacity = 0.5;
                                    // first child could be a monitor to our right
                                    fc.MoveTo(fw.Right, fw.Top);
                                    fc.Owner = fvs;
                                    fc.BackColor = Color.Transparent;

                                    fc.Width = 400 / 4;
                                    fc.Height = 400 / 4;

                                    VirtualScreenUpdate();



                                    fc.LocationChanged +=
                                        delegate
                                        {
                                            VirtualScreenUpdate();

                                        };

                                    var fcShadow = CreateShadow(fc);
                                    Shadows.Add(fcShadow);

                                    var token = new { child_id = random.Next(), fc };

                                    ListOfChildren.Add(token);

                                    #region FormClosing
                                    w.onbeforeunload +=
                                        delegate
                                        {
                                            if (fc == null)
                                                return;

                                            w = null;

                                            ct.Stop();
                                            fc.Close();
                                            fc = null;
                                        };

                                    Native.window.onbeforeunload +=
                                        delegate
                                        {
                                            if (w == null)
                                                return;

                                            w.close();
                                            w = null;
                                        };

                                    fc.FormClosing +=
                                        delegate
                                        {

                                            if (w == null)
                                                return;

                                            ListOfChildren.Remove(token);
                                            Shadows.Remove(fcShadow);

                                            fc = null;

                                            w.close();
                                            w = null;
                                        };
                                    #endregion



                                    bind(w, fc);


                                };
                        }
                    );
                };
            #endregion





            Native.document.documentElement.style.overflow = IStyle.OverflowEnum.hidden;
        }
        /// <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)
        {

            // Initialize ApplicationSprite
            sprite.AttachSpriteToDocument();


            // how did it work before?
#if v

            #region visualize
            Action<bool, byte[], Action<double, double, Action<double>, IWindow>> visualize_and_getpadding = null;

            visualize_and_getpadding =
                (allowpadding, bytes, set_padding) =>
                {
                    var r = new BinaryReader(new MemoryStream(bytes));

                    var floats = new double[bytes.Length / 4];

                    //Console.WriteLine("floats " + new { floats.Length });


                    for (int i = 0; i < floats.Length; i++)
                    {
                        // X:\jsc.svn\core\ScriptCoreLib\JavaScript\BCLImplementation\System\IO\BinaryReader.cs
                        // do we do floats?
                        floats[i] = r.ReadSingle();
                    }

                    var paddingmode_yellow = allowpadding;
                    var paddingsamples_yellow = 0;
                    var paddingmode_yellow_agg = 0.0;
                    var paddingmode_yellow_grace = 411;

                    var paddingmode_red = allowpadding;
                    var paddingsamples_red = 0;
                    var paddingmode_red_agg = 0.0;
                    var paddingmode_red_grace = 411;


            #region max
                    var min = 0.0;
                    var minset = false;

                    var max = 0.0;
                    var maxset = false;


                    for (int ix = 0; ix < floats.Length; ix += 2)
                    {
                        //                                    arg[0] is typeof System.Single
                        //script: error JSC1000: No implementation found for this native method, please implement [static System.Console.WriteLine(System.Single)]

                        var l0 = floats[ix];
                        var r0 = floats[ix + 1];

                        if (l0 != 0)
                            if (minset)
                            {
                                min = Math.Min(min, l0);
                            }
                            else
                            {
                                min = l0;
                                minset = true;
                            }

                        if (maxset)
                        {
                            max = Math.Max(max, l0);
                        }
                        else
                        {
                            max = l0;
                            maxset = true;
                        }
                    }

                    var absmax = max.Max(Math.Abs(min));

            #endregion


            #region paddingmode_yellow
                    for (int ix = 0; ix < floats.Length; ix += 2)
                    {
                        //                                    arg[0] is typeof System.Single
                        //script: error JSC1000: No implementation found for this native method, please implement [static System.Console.WriteLine(System.Single)]

                        var l0 = floats[ix];
                        var r0 = floats[ix + 1];




                        if (paddingmode_yellow)
                        {
                            // discard noise
                            if (Math.Abs(l0) > 0.08 * absmax)
                                paddingmode_yellow_agg += Math.Abs(l0);
                        }

                        if (paddingmode_yellow_agg > absmax * 2.1)
                        {
                            if (Math.Abs(l0) < 0.02 * absmax)
                            {
                                paddingmode_yellow = false;
                            }
                        }

                        if (paddingmode_yellow)
                        {
                            paddingsamples_yellow++;

                            if (paddingmode_yellow_agg > absmax * 3.2)
                            {
                                if (paddingmode_yellow_grace > 0)
                                {
                                    paddingmode_yellow_grace--;
                                }
                                else
                                {
                                    // rollback
                                    paddingsamples_yellow -= 411;
                                    paddingmode_yellow = false;
                                }
                            }
                        }

                    }
            #endregion

                    // count down while near zero, then wait for zero

            #region paddingmode_red
                    for (int ix = floats.Length - 1; ix >= 0; ix -= 2)
                    {
                        var l0 = floats[ix];
                        var r0 = floats[ix + 1];


                        if (paddingmode_red)
                        {
                            // discard noise
                            if (Math.Abs(l0) > 0.08 * absmax)
                                paddingmode_red_agg += Math.Abs(l0);
                        }

                        if (paddingmode_red_agg > absmax * 2.1)
                        {
                            if (Math.Abs(l0) < 0.02 * absmax)
                            {
                                paddingmode_red = false;
                            }
                        }

                        if (paddingmode_red)
                        {
                            paddingsamples_red++;

                            if (paddingmode_red_agg > absmax * 3.2)
                            {
                                if (paddingmode_red_grace > 0)
                                {
                                    paddingmode_red_grace--;
                                }
                                else
                                {
                                    // rollback
                                    paddingsamples_red -= 411;
                                    paddingmode_red = false;
                                }
                            }
                        }

                    }
            #endregion




                    var w = new IWindow();

                    w.onload +=
                        delegate
                        {
                            Console.WriteLine("onload");

                            try
                            {

                                //BitConverter.ToSingle(
                                w.document.body.style.margin = "0px";

                                // verbose huh. svg::svg?
                                var svg = new ISVGSVGElement().AttachTo(w.document.body);


                                var path_current = new ISVGPathElement().AttachTo(svg);
                                path_current.setAttribute("style", "stroke-width: 5; stroke: blue; fill: none;");


                                var path = new ISVGPathElement().AttachTo(svg);
                                path.setAttribute("style", "stroke: black; fill: none;");

                                var path_loop2 = new ISVGPathElement().AttachTo(svg);
                                path_loop2.setAttribute("style", "stroke: green; fill: none;");


                                var xw = new StringBuilder().Append("M0,400 ");






                                // done { min = 7.847271400218976e-44, max = 2.320612754833406e-38, paddingsamples = 1337 }

                                w.document.body.style.minHeight = 800 + "px";

                                var scalex = 4 / 44.1;

                                w.document.body.style.minWidth = floats.Length * scalex * 2 + "px";
                                w.document.body.style.overflow = IStyle.OverflowEnum.auto;

                                // we should have 4096 stereo samples
                                var samples = floats.Length;
                                var samplesperchannel = samples / 2;






            #region xw
                                for (int ix = 0; ix < floats.Length; ix += 2)
                                {
                                    //                                    arg[0] is typeof System.Single
                                    //script: error JSC1000: No implementation found for this native method, please implement [static System.Console.WriteLine(System.Single)]

                                    var l0 = floats[ix];
                                    var r0 = floats[ix + 1];








                                    // 0 is -60db
                                    // max is 0db



                                    // http://audio.tutsplus.com/articles/general/all-youll-ever-need-to-know-about-samples-and-bits/


                                    //iy = (200.0 - l0 * 1E37 * 200);
                                    var iy = (400.0 - l0 * 400.0);

                                    xw.Append(" L" + (ix * scalex) + "," + iy);


                                    //Console.WriteLine("" + ReadFloat32(i));
                                }
            #endregion

            #region xw_loop2
                                var xw_loop2 = new StringBuilder();

                                for (int ix = paddingsamples_yellow * 2; ix < floats.Length - paddingsamples_red * 2; ix += 2)
                                {
                                    //                                    arg[0] is typeof System.Single
                                    //script: error JSC1000: No implementation found for this native method, please implement [static System.Console.WriteLine(System.Single)]

                                    var l0 = floats[ix];
                                    var r0 = floats[ix + 1];

                                    var iy = (400.0 - l0 * 400.0);

                                    if (xw_loop2.ToString().Length == 0)
                                        xw_loop2.Append(" M" + ((2 * (samplesperchannel - paddingsamples_red - paddingsamples_yellow) * scalex) + ((ix + 1) * scalex)) + "," + iy);
                                    else
                                        xw_loop2.Append(" L" + ((2 * (samplesperchannel - paddingsamples_red - paddingsamples_yellow) * scalex) + ((ix + 1) * scalex)) + "," + iy);

                                }
            #endregion


                                // A frame rate of 44,100 is 44,100 samples per SECOND, or 44.1 kHz.

                                var duration_seconds = samplesperchannel / 44100;

                                w.document.title = new { samplesperchannel, paddingsamples_yellow, paddingsamples_red, duration_seconds }.ToString();

                                Console.WriteLine("done " + new { min, max, paddingsamples_yellow, paddingsamples_red });



                                //xw.Append(" L30,210");

                                path.d = xw.ToString();
                                path_loop2.d = xw_loop2.ToString();

                                var path_zero = new ISVGPathElement().AttachTo(svg);
                                path_zero.setAttribute("style", "stroke-width: 1; stroke: gray; fill: none;");
                                path_zero.d = "M0,400 L" + (2 * samplesperchannel * scalex) + ",400";



                                //var path_leftpadding = new ISVGPathElement().AttachTo(svg);
                                //path_leftpadding.setAttribute("style", "stroke-width: 5; stroke: red; fill: none;");
                                //path_leftpadding.d = "M0,400 L" + (2 * paddingsamples * scalex) + ",400";


                                var path_leftpadding_yellow = new ISVGPathElement().AttachTo(svg);
                                path_leftpadding_yellow.setAttribute("style", "stroke-width: 3; stroke: yellow; fill: none;");
                                path_leftpadding_yellow.d = "M0,400 L" + (2 * paddingsamples_yellow * scalex) + ",400";

                                var path_leftpadding_red = new ISVGPathElement().AttachTo(svg);
                                path_leftpadding_red.setAttribute("style", "stroke-width: 3; stroke: red; fill: none;");
                                path_leftpadding_red.d = "M" + (2 * (samplesperchannel - paddingsamples_red) * scalex) + ",400 L" + (2 * (samplesperchannel - 0) * scalex) + ",400";


                                Action<double> set_position =
                                     position =>
                                     {
                                         var x = (2 * position * scalex);
                                         path_current.d = "M" + x + ",50 L" + x + ",750 L" + (x + MP3PitchLoop.BLOCK_SIZE * 2 * scalex) + ",750 L" + (x + MP3PitchLoop.BLOCK_SIZE * 2 * scalex) + ",50 L" + x + ",50";

                                     };


                                set_padding(
                                    paddingsamples_yellow,
                                    paddingsamples_red,
                                    set_position,
                                    w
                                );

                                set_position(paddingsamples_yellow);

                            }
                            catch (Exception error)
                            {
                                Console.WriteLine("error " + new { error.Message, error });
                            }

                            Console.WriteLine("done");

                        };

                };
            #endregion



      

            #region f
            Func<IHTMLButton, Action<string, PlayAtAndAllowToStop>> f =
                x =>
                     (base64, playat) =>
                     {
                         var bytes = Convert.FromBase64String(base64);

                         visualize_and_getpadding(
                             true,
                             bytes,
                             (paddingleft, paddingright, set_position, w) =>
                             {
                                 var toolbar = new IHTMLDiv().AttachTo(w.document.body);

                                 toolbar.style.SetLocation(4, 4);
                                 toolbar.style.position = IStyle.PositionEnum.@fixed;

                                 new IHTMLButton { innerText = "play" }.AttachTo(toolbar).WhenClicked(
                                     delegate
                                     {
                                         playat(
                                             "" + paddingleft,
                                             "" + paddingright,
                                             yield_stop: stop =>
                                              {

                                                  var stopbtn = new IHTMLButton { innerText = "Stop" };

                                                  stopbtn.WhenClicked(
                                                      delegate
                                                      {
                                                          stop();
                                                          stopbtn.Orphanize();
                                                      }
                                                  );

                                                  stopbtn.AttachTo(toolbar);
                                              },
                                              yield_position_anddiagnostics: (position, diagnostics) =>
                                              {
                                                  set_position(Convert.ToDouble(position));

                                                  if (!string.IsNullOrEmpty(diagnostics))
                                                  {
                                                      Console.WriteLine(diagnostics);

                                                      var diagnostics_bytes = Convert.FromBase64String(diagnostics);

                                                      visualize_and_getpadding(
                                                          false,
                                                          diagnostics_bytes,
                                                          delegate
                                                          { }
                                                      );

                                                  }
                                              }


                                         );
                                     }
                                 );


                             }
                         );
                     };
            #endregion


            page.VisualizeDiesel.WhenClicked(
                delegate
                {
                    sprite.BytesForDiesel(f(page.VisualizeDiesel));
                }
            );

            page.VisualizeHelicopter.onclick += delegate
            {
                sprite.BytesForHelicopter(f(page.VisualizeHelicopter));
            };

            page.VisualizeJeep.onclick += delegate
            {
                sprite.BytesForJeep(f(page.VisualizeJeep));

            };

            page.VisualizeTone.onclick += delegate
            {

                sprite.BytesForTone(f(page.VisualizeTone));

            };

            page.VisualizeSandrun.onclick += delegate
            {

                sprite.BytesForSandrun(f(page.VisualizeSandrun));

            };
#endif

            page.PlayDiesel.onclick += delegate
            {
                sprite.PlayDiesel();
            };

            page.PlayHelicopter.onclick += delegate
            {
                sprite.Playhelicopter1();
            };



            page.PlayJeep.onclick += delegate
            {
                sprite.PlayJeep();
            };






            page.PlayTone.onclick += delegate
            {
                sprite.PlayTone();
            };




            page.PlaySandrun.onclick += delegate
            {
                sprite.PlaySandrun();
            };



        }