public void Initialize()
        {
            createButton();

            hostControl      = KCVUIHelper.KCVWindow.FindVisualChildren <KanColleHost>().First();
            contentContainer = hostControl.Parent as Grid;
            pluginControl    = KCVUIHelper.KCVContent;

            hostControl.ZoomFactor = this.BrowserZoomFactor / 100.0;
            switchLayout(CurrentLayout);
        }
        public static void SetMiniWindow(this KanColleHost kanColleHost, double captionHeight)
        {
            if (kanColleHost.WebBrowser == null)
            {
                return;
            }

            kanColleHost.Update();
            Window win = Window.GetWindow(kanColleHost);

            win.Width     = kanColleHost.WebBrowser.ActualWidth;
            win.MinHeight = kanColleHost.WebBrowser.ActualHeight + captionHeight + 23;
            win.Height    = win.MinHeight;
        }
        public void Startup()
        {
            #region Read data JSON
            try
            {
                HttpWebRequest rq = WebRequest.Create("https://raw.githubusercontent.com/KC3Kai/KC3Kai/master/src/data/nodes.json") as HttpWebRequest;
                rq.Timeout = 5000;
                HttpWebResponse response = rq.GetResponse() as HttpWebResponse;

                using (var reader = new StreamReader(response.GetResponseStream()))
                {
                    var bytes      = Encoding.UTF8.GetBytes(reader.ReadToEnd());
                    var serializer = new DataContractJsonSerializer(typeof(overlayData), new DataContractJsonSerializerSettings {
                        UseSimpleDictionaryFormat = true
                    });
                    using (var stream = new MemoryStream(bytes))
                    {
                        var rawResult = serializer.ReadObject(stream) as overlayData;
                        this.overlayTableData = rawResult;
                    }
                }
            }
            catch
            {
                return;
            }
            #endregion

            #region Find webbrowser and add overlay element
            Grabacr07.KanColleViewer.Application app = Grabacr07.KanColleViewer.Application.Instance as Grabacr07.KanColleViewer.Application;
            KanColleHost host = null;

            this.dispatcher = app.Dispatcher;
            this.dispatcher.Invoke(() =>
            {
                host = FindElement <KanColleHost>(app.MainWindow.Content as UIElement);
                if (host == null)
                {
                    return;
                }

                try
                {
                    var browser  = host.WebBrowser;
                    var document = browser.Document as HTMLDocument;
                    if (document == null)
                    {
                        return;
                    }

                    var gameFrame = document.getElementById("game_frame");
                    if (gameFrame == null)
                    {
                        if (document.url.Contains(".swf?"))
                        {
                            gameFrame = document.body;
                        }
                    }

                    var target = gameFrame?.document as HTMLDocument;
                    if (target != null)
                    {
                        target.createStyleSheet().cssText = "#battleinfo_display_overlay { position:fixed; left:0; top:0; width:800px; height:480px; z-index:9145; pointer-events:none; font:bold 22px sans-serif; }"
                                                            + "@keyframes fadeOut { from { opacity: 1 } to { opacity: 0 } }"
                                                            + "#battleinfo_display_overlay > .overlay_node, #battleinfo_display_overlay > .overlay_marker { animation-duration: 4s; animation-fill-mode: both; animation-delay: 10s; }"
                                                            + "#battleinfo_display_overlay > .overlay_node { position:absolute; display:inline-block; text-shadow: #F5F5F5 1px 1px 2px, #F5F5F5 0 0 2px; color:#333; font:inherit; animation-name: fadeOut }"
                                                            + "#battleinfo_display_overlay > .overlay_marker { position:absolute; display:block; border:2px solid #37373f; border-radius:9999px; background-color:#F5F5F5; animation-name: fadeOut }";

                        layer    = target.createElement("div");
                        layer.id = "battleinfo_display_overlay";
                        target.appendChild(layer as IHTMLDOMNode);
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex);
                    return;
                }
            });
            #endregion

            #region HTTP captures
            var proxy = KanColleClient.Current.Proxy;

            proxy.api_port.Subscribe(x => this.resetLayer());

            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_battle_midnight/battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_battle_midnight/sp_midnight").Subscribe(x => this.resetLayer());
            proxy.api_req_combined_battle_airbattle.Subscribe(x => this.resetLayer());
            proxy.api_req_combined_battle_battle.Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/battle_water").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/midnight_battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/sp_midnight").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_practice/battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_practice/midnight_battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_practice/battle_result").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_sortie/airbattle").Subscribe(x => this.resetLayer());
            proxy.api_req_sortie_battle.Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_sortie/ld_airbattle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/ld_airbattle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/ec_battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/each_battle").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/each_battle_water").Subscribe(x => this.resetLayer());
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_combined_battle/ec_midnight_battle").Subscribe(x => this.resetLayer());
            proxy.api_req_sortie_battleresult.Subscribe(x => this.resetLayer());
            proxy.api_req_combined_battle_battleresult.Subscribe(x => this.resetLayer());

            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_map/start").TryParse <map_start_next>().Subscribe(x => this.updateLayer(x.Data));
            proxy.ApiSessionSource.Where(x => x.Request.PathAndQuery == "/kcsapi/api_req_map/next").TryParse <map_start_next>().Subscribe(x => this.updateLayer(x.Data));
            #endregion
        }