internal void FillVirtualGroupStates()
            {
                Dictionary <string, bool> tmpVGS = new Dictionary <string, bool>();

                foreach (AccTriggerInfo Part in CurOutfitTriggerInfo.Parts)
                {
                    if (Part.Kind >= 9)
                    {
                        if (!Part.Group.IsNullOrEmpty())
                        {
                            if (VirtualGroupStates.ContainsKey(Part.Group))
                            {
                                tmpVGS[Part.Group] = VirtualGroupStates[Part.Group];
                            }
                            else
                            {
                                tmpVGS[Part.Group] = true;
                            }
                        }
                    }
                }
                VirtualGroupStates = tmpVGS.ToDictionary(entry => entry.Key, entry => entry.Value);
            }
            internal void SyncAllAccToggle()
            {
                Logger.Log(DebugLogLevel, $"[SyncAllAccToggle][{ChaControl.chaFile.parameter?.fullname}] Fired!!");

                if ((MakerAPI.InsideMaker) && (!CharaMakerPreview.Value))
                {
#if DEBUG
                    Logger.LogInfo($"[SyncAllAccToggle][{ChaControl.chaFile.parameter?.fullname}] Disabled by config");
#endif
                    return;
                }
                if (!TriggerEnabled)
                {
                    Logger.Log(DebugLogLevel, $"[SyncAllAccToggle][{ChaControl.chaFile.parameter?.fullname}] TriggerEnabled false");
                    return;
                }

                foreach (AccTriggerInfo Part in CurOutfitTriggerInfo.Parts)
                {
                    if (MathfEx.RangeEqualOn(0, Part.Kind, 7))
                    {
                        int  state = ChaControl.fileStatus.clothesState[Part.Kind];
                        bool vis   = Part.State[state];
                        Logger.Log(DebugLogLevel, $"[SyncAllAccToggle][{ChaControl.chaFile.parameter?.fullname}][slot: {Part.Slot}][kind: {Part.Kind}][state: {state}][vis: {vis}]");
                        ChaControl.SetAccessoryState(Part.Slot, vis);
                    }
                    else if ((Part.Kind >= 9) && (!Part.Group.IsNullOrEmpty()))
                    {
                        bool vis = true;
                        if (VirtualGroupStates.ContainsKey(Part.Group))
                        {
                            vis = VirtualGroupStates[Part.Group] ? Part.State[0] : Part.State[3];
                        }
                        ChaControl.SetAccessoryState(Part.Slot, vis);
                    }
                }
            }
            internal void AccSlotChangedHandler(int SlotIndex, bool Skip = false)
            {
                Logger.Log(DebugLogLevel, $"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}] Fired!!");

                if (!MakerAPI.InsideAndLoaded)
                {
                    return;
                }

                if (!TriggerEnabled)
                {
                    Logger.Log(DebugLogLevel, $"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}] TriggerEnabled false");
                    return;
                }
                CurOutfitTriggerInfo = CharaTriggerInfo.ElementAtOrDefault(CurrentCoordinateIndex);
                if (CurOutfitTriggerInfo == null)                 // basically won't happen
                {
                    Logger.Log(DebugLogLevel, $"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}] CurOutfitTriggerInfo is null");
                    return;
                }

                CheckOutfitTriggerInfoCount(CurrentCoordinateIndex);

                Logger.Log(DebugLogLevel, $"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}][SlotIndex]: {SlotIndex}");

                List <ChaFileAccessory.PartsInfo> PartsInfo = CharaAccInfo;

                ChaFileAccessory.PartsInfo PartInfo = PartsInfo.ElementAtOrDefault(SlotIndex);
                if ((PartInfo == null) || (CurOutfitTriggerInfo.Parts.ElementAtOrDefault(SlotIndex) == null))
                {
                    Logger.LogError($"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}][PartInfo: {PartInfo}][CurSlotTriggerInfo: {CurSlotTriggerInfo}]");
                    return;
                }

                CopySlotTriggerInfo(CurOutfitTriggerInfo.Parts[SlotIndex], CurSlotTriggerInfo);

                if (!Skip)
                {
                    if ((CurSlotTriggerInfo.Kind > -1) && (PartInfo.type == 120))
                    {
                        CurOutfitTriggerInfo.Parts[SlotIndex] = new AccTriggerInfo(SlotIndex);
                        Logger.LogMessage($"AccTriggerInfo for Coordinate {CurrentCoordinateIndex} Slot {CurSlotTriggerInfo.Slot + 1:00} has been reset");
                    }
                }

                int ddASSListVal = CurSlotTriggerInfo.Kind < 10 ? ddASSListVals.IndexOf(CurSlotTriggerInfo.Kind) : CurSlotTriggerInfo.Kind;

                GameObject.Find("ddASSList").GetComponentInChildren <TMP_Dropdown>().value = ddASSListVal;
                GameObject.Find("tglASS0").GetComponentInChildren <Toggle>().isOn          = CurSlotTriggerInfo.State[0];
                GameObject.Find("tglASS1").GetComponentInChildren <Toggle>().isOn          = CurSlotTriggerInfo.State[1];
                GameObject.Find("tglASS2").GetComponentInChildren <Toggle>().isOn          = CurSlotTriggerInfo.State[2];
                GameObject.Find("tglASS3").GetComponentInChildren <Toggle>().isOn          = CurSlotTriggerInfo.State[3];

                int refIndex = ddASSListVal < 10 ? ddASSListVal : 9;

                GameObject.Find("tglASS0").GetComponentInChildren <TextMeshProUGUI>().alpha = clothesStates[refIndex][0] ? 1f : 0.2f;
                GameObject.Find("tglASS1").GetComponentInChildren <TextMeshProUGUI>().alpha = clothesStates[refIndex][1] ? 1f : 0.2f;
                GameObject.Find("tglASS2").GetComponentInChildren <TextMeshProUGUI>().alpha = clothesStates[refIndex][2] ? 1f : 0.2f;
                GameObject.Find("tglASS3").GetComponentInChildren <TextMeshProUGUI>().alpha = clothesStates[refIndex][3] ? 1f : 0.2f;

                foreach (string group in VirtualGroupNames)
                {
                    Object.Destroy(GameObject.Find(group));
                }
                VirtualGroupNames.Clear();

                FillVirtualGroupStates();

                AnchorOffsetMinY = (int)GameObject.Find("tglASS0").GetComponent <RectTransform>().offsetMin.y - 80;

                List <string> names = VirtualGroupStates.OrderBy(x => x.Key).Select(x => x.Key).ToList <string>();

                foreach (string group in names)
                {
                    CreateMakerVirtualGroupToggle(group);
                }

                GameObject    accw   = GameObject.Find("04_AccessoryTop/AcsMoveWindow01");
                RectTransform windRt = accw.transform.Find("BasePanel/imgWindowBack").GetComponent <RectTransform>();

                windRt.offsetMin = new Vector2(0, ContainerOffsetMinY - 40 * names.Count());

                Logger.Log(DebugLogLevel, $"[AccSlotChangedHandler][{ChaControl.chaFile.parameter?.fullname}][Slot: {CurSlotTriggerInfo.Slot}][Kind: {CurSlotTriggerInfo.Kind}][State: {CurSlotTriggerInfo.State[0]}|{CurSlotTriggerInfo.State[1]}|{CurSlotTriggerInfo.State[2]}|{CurSlotTriggerInfo.State[3]}]");

                ChaControl.StartCoroutine(CoroutineSyncAllAccToggle(CoroutineSlotChangeDelay.Value));
            }