/// <summary>
        /// Refreshes the available mass of each element in the POI.
        /// </summary>
        /// <param name="panel">The parent info panel.</param>
        /// <param name="harvestable">The POI to be harvested.</param>
        private void RefreshElements(SpacePOISimpleInfoPanel panel, HarvestablePOIStates.
                                     Instance harvestable)
        {
            var elementRows = panel.elementRows;

            if (harvestable != null)
            {
                // Shared dictionary, does not allocate
                var   weightedElements = harvestable.configuration.GetElementsWithWeights();
                float total            = 0.0f;
                foreach (var pair in weightedElements)
                {
                    float mass = pair.Value;
                    total += mass;
                }
                // Avoid NaN
                total = Math.Max(total, 0.01f);
                foreach (var pair in weightedElements)
                {
                    Tag elementTag = new Tag(pair.Key.ToString());
                    // It is already visible, and in the correct order
                    if (elementRows.TryGetValue(elementTag, out GameObject row) && row.
                        TryGetComponent(out HierarchyReferences hr))
                    {
                        string text = GameUtil.GetFormattedPercent(pair.Value * 100.0f /
                                                                   total);
                        var label = hr.GetReference <LocText>("ValueLabel");
                        if (label.text != text)
                        {
                            label.SetText(text);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Initializes the available mass by element display.
        /// </summary>
        /// <param name="panel">The parent info panel.</param>
        /// <param name="harvestable">The POI to be harvested.</param>
        /// <param name="details">The panel to refresh.</param>
        private void InitElements(SpacePOISimpleInfoPanel panel, HarvestablePOIStates.
                                  Instance harvestable, CollapsibleDetailContentPanel details)
        {
            var elementRows  = panel.elementRows;
            var existingRows = DictionaryPool <Tag, GameObject, SpacePOISimpleInfoPanel> .
                               Allocate();

            foreach (var pair in panel.elementRows)
            {
                existingRows[pair.Key] = pair.Value;
            }
            if (harvestable != null)
            {
                // Shared dictionary, does not allocate
                var sortedElements = ListPool <ElementWeight, SpacePOISimpleInfoPanel> .
                                     Allocate();

                sortedElements.AddRange(harvestable.configuration.GetElementsWithWeights());
                sortedElements.Sort(SortElementsByMassComparer.Instance);
                int n = sortedElements.Count;
                for (int i = 0; i < n; i++)
                {
                    var       pair       = sortedElements[i];
                    SimHashes element    = pair.Key;
                    Tag       elementTag = new Tag(element.ToString());
                    if (!elementRows.TryGetValue(elementTag, out GameObject row))
                    {
                        row = Util.KInstantiateUI(panel.simpleInfoRoot.iconLabelRow, details.
                                                  Content.gameObject, true);
                        elementRows[elementTag] = row;
                    }
                    else
                    {
                        row.SetActive(true);
                    }
                    if (row.TryGetComponent(out HierarchyReferences hr))
                    {
                        var uiSprite = Def.GetUISprite(elementTag, "ui", false);
                        var icon     = hr.GetReference <Image>("Icon");
                        if (uiSprite != null)
                        {
                            icon.sprite = uiSprite.first;
                            icon.color  = uiSprite.second;
                        }
                        hr.GetReference <LocText>("NameLabel").SetText(ElementLoader.
                                                                       FindElementByHash(element).name);
                        hr.GetReference <LocText>("ValueLabel").alignment = TMPro.
                                                                            TextAlignmentOptions.MidlineRight;
                    }
                    existingRows.Remove(elementTag);
                }
                sortedElements.Recycle();
            }
            // Turn off all rows that were not turned on
            foreach (var pair in existingRows)
            {
                pair.Value.SetActive(false);
            }
            existingRows.Recycle();
        }
 internal LastSelectionDetails(GameObject target)
 {
     if (target.TryGetComponent(out ClusterGridEntity gridEntity) && gridEntity is
         HarvestablePOIClusterGridEntity asteroid)
     {
         asteroidField = asteroid;
         harvestable   = target.GetSMI <HarvestablePOIStates.Instance>();
         artifact      = target.GetSMI <ArtifactPOIStates.Instance>();
     }
        /// <summary>
        /// Refreshes the maximum available mass heading.
        /// </summary>
        /// <param name="harvestable">The POI to be harvested.</param>
        private void RefreshMassHeader(HarvestablePOIStates.Instance harvestable)
        {
            string mass = GameUtil.GetFormattedMass(harvestable.poiCapacity);

            if (massLabel.text != mass)
            {
                massLabel.SetText(mass);
            }
        }