public HeatmapWindow(CancellationTokenSource cts, DemoData demo, HashSet <int> selectedPlayers, int selectionStart, int selectionEnd, int radius)
        {
            InitializeComponent();

            this.demo            = demo;
            this.selectedPlayers = selectedPlayers;
            this.selectionStart  = selectionStart;
            this.selectionEnd    = selectionEnd;

            minimapImage.Source = Assets.GetMinimap(demo.MapName);

            _cts  = cts;
            _ct   = cts.Token;
            _task = Task.Run(() =>
            {
                var counter = 0;

                using (var heatmap = new Heatmap(1024, 1024))
                    using (var stroke = new HeatmapStamp(radius))
                    {
                        for (int i = selectionStart; i <= selectionEnd; i++)
                        {
                            _ct.ThrowIfCancellationRequested();

                            foreach (var player in demo.ReadPlayerInfos(i))
                            {
                                if (!selectedPlayers.Contains(player.EntityID))
                                {
                                    continue;
                                }

                                if (player.State.Team == DemoInfo.Team.Spectate)
                                {
                                    continue;
                                }

                                if (!player.State.IsAlive)
                                {
                                    continue;
                                }

                                var realPos = demo.WorldSpaceToMinimapSpace(new Vector(player.Position.PositionX, player.Position.PositionY));

                                heatmap.AddPoint((int)realPos.X, (int)realPos.Y, stroke);
                            }

                            if ((++counter & 0xF) == 0)
                            {
                                var percentage = (double)(i - selectionStart) / (selectionEnd - selectionStart);

                                Dispatcher.Invoke(() =>
                                {
                                    progressBar.Value = percentage;
                                });
                            }
                        }

                        Dispatcher.Invoke(() =>
                        {
                            heatmapImage.Source = heatmap.CreateHeatmap();
                        });
                    }
            }, _ct);
        }