123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699 |
- using System.Reflection;
- namespace labelUtility
- {
- #if UNITY_EDITOR
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Xml;
- using UnityEditor;
- using UnityEngine;
- using UnityEngine.UI;
- [Serializable]
- public class RegistTarget
- {
- public string Name;
- public bool Force;
- public bool Ignore;
- //public bool CustomName;
- public bool CustomEvent = true;
- public Transform Transform;
- public ComponentType Type;
- }
- [Serializable]
- public class ComponentEventString
- {
- public ComponentType ComponentType;
- public List<string> RegistStrings;
- public List<string> MethodNames;
- }
- [Serializable]
- public class LabelSet //todo 更新
- {
- public string Name;
- public UtilityType UtilityType;
- public string LabelScriptPath;
- public string LabelScriptName;
- public string LabePrefix = "public static string";
- public TextAsset LabelScript;
- public string ComponentScriptPath;
- public string ComponentScriptName;
- public string DerivedString;
- public string RegistMethodString;
- public string ComponentPrefix = "private";
- public string NameExcludeString;
- public string RegistString;
- public List<string> RegistExtraLines;
- public TextAsset ComponentScript;
- public List<TextAsset> Languages; //todo 需要更新为LanguageXml
- public List<GameObject> Prefabs;
- public bool FoldOut;
- public float TotalHeight;
- public List<ComponentType> RegistTypes = new List<ComponentType>();
- public List<RegistTarget> RegistTargets = new List<RegistTarget>();
- }
- [Serializable]
- public enum ComponentType //todo 更新
- {
- None,
- Text,
- Slider,
- Image,
- Button,
- InputField,
- Transform,
- CanvasGroup,
- RectTransform,
- SpriteRenderer,
- VirtualScrollRectPlus,
- }
- public enum UtilityType
- {
- XmlLabel,
- PrefabLabel,
- Regist,
- }
- public class LabelUtility : MonoBehaviour
- {
- #region Config
- public List<string> DllNames;
- public List<ComponentEventString> EventStrings;
- public List<LabelSet> LabelSets;
- public static string StartMark = "//StartMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string EndMark = "//EndMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string RegistStartMark = "//RegistStartMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string RegistEndMark = "//RegistEndMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string EventStartMark = "//EventStartMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string EventEndMark = "//EventEndMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string RegistEventStartMark = "//RegistEventStartMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string RegistEventEndMark = "//RegistEventEndMark-Used by LabelUtility-Do not remove"; //todo 更新
- public static string Prefix = "public static string ";
- #endregion
- public static void CreateLabelScript(LabelSet labelSet, bool showWarning = true, bool auto = false)
- {
- if (showWarning)
- {
- if (!EditorUtility.DisplayDialog("注意", "新建LabelScript?", "确定", "取消"))
- {
- return;
- }
- }
- if (!auto)
- {
- auto = EditorUtility.DisplayDialog("提示", "是否自动提取标签", "确定", "取消");
- }
- string scriptContent = "";
- foreach (var dllName in InstanceManager.SearchInstance<LabelUtility>().DllNames)
- {
- scriptContent += $"using {dllName};\r\n";
- }
- scriptContent += "\r\n";
- scriptContent += $"public class {labelSet.LabelScriptName}";
- scriptContent += "\r\n";
- scriptContent += $"{{\r\n\t#region Config\r\n\r\n\t{StartMark}\r\n\t{EndMark}\r\n\r\n\t#endregion\r\n}}";
- labelSet.LabelScript = CreateScript(labelSet.LabelScriptName, labelSet.LabelScriptPath, scriptContent);
- if (auto)
- {
- if (labelSet.UtilityType == UtilityType.XmlLabel)
- {
- CreateLabelFromLanguageXml(labelSet, false);
- }
- else if (labelSet.UtilityType == UtilityType.Regist || labelSet.UtilityType == UtilityType.PrefabLabel)
- {
- CreateLabelFromPrefab(labelSet, false);
- }
- }
- }
- public static void CreateComponentScript(LabelSet labelSet, bool showWarning = true, bool regist = false)
- {
- if (showWarning)
- {
- if (!EditorUtility.DisplayDialog("注意", "新建ComponentScript?", "确定", "取消"))
- {
- return;
- }
- }
- if (!regist)
- {
- regist = EditorUtility.DisplayDialog("提示", "是否自动注册", "确定", "取消");
- }
- string scriptContent = "";
- foreach (var dllName in InstanceManager.SearchInstance<LabelUtility>().DllNames)
- {
- scriptContent += $"using {dllName};\r\n";
- }
- scriptContent += "\r\n";
- scriptContent += $"public class {labelSet.ComponentScriptName}";
- if (string.IsNullOrEmpty(labelSet.DerivedString))
- {
- scriptContent += "\r\n";
- }
- else
- {
- scriptContent += $" : {labelSet.DerivedString}\r\n";
- }
- scriptContent += $"{{\r\n\t#region Config\r\n\r\n\t{StartMark}\r\n\t{EndMark}\r\n\r\n\t#endregion\r\n";
- scriptContent += "\r\n";
- if (!string.IsNullOrEmpty(labelSet.RegistMethodString))
- {
- scriptContent += $"\t{labelSet.RegistMethodString}\r\n\t{{\r\n";
- scriptContent += $"\t\t{RegistStartMark}\r\n";
- scriptContent += $"\t\t{RegistEndMark}\r\n";
- scriptContent += $"\t\t{RegistEventStartMark}\r\n";
- scriptContent += $"\t\t{RegistEventEndMark}\r\n";
- scriptContent += $"\t}}\r\n";
- }
- scriptContent += "\r\n";
- scriptContent += $"\t{EventStartMark}\r\n";
- scriptContent += $"\t{EventEndMark}\r\n";
- scriptContent += $"}}";
- labelSet.ComponentScript = CreateScript(labelSet.ComponentScriptName, labelSet.ComponentScriptPath, scriptContent);
- if (regist)
- {
- CreateComponentsFromPrefab(labelSet, false);
- }
- }
- private static TextAsset CreateScript(string scriptName, string scriptPath, string content)
- {
- string directory = scriptPath.TrimEnd('/', '\\') + "/";
- if (directory.Length < 6 || directory.Substring(0, 6).ToLower() != "assets")
- {
- throw new Exception("ScripPath必须位置Assets目录内");
- }
- if (!Directory.Exists(directory))
- {
- throw new Exception("文件夹不存在");
- }
- if (string.IsNullOrEmpty(scriptName) || scriptName.Any(Path.GetInvalidFileNameChars().Contains))
- {
- throw new Exception("ScripName包含无效字符");
- }
- string fullPath = $"{scriptPath}/{scriptName}.cs";
- if (File.Exists(fullPath))
- {
- throw new Exception($"已经存在一个 {fullPath}");
- }
- File.WriteAllText(fullPath, content);
- AssetDatabase.Refresh();
- return AssetDatabase.LoadAssetAtPath<TextAsset>(fullPath);
- }
- public static void CreateLabelFromPrefab(LabelSet labelSet, bool showWarning = true, bool regist = false) //todo 更新
- {
- if (labelSet.LabelScript == null)
- {
- Debug.LogError("LabelScript is null");
- return;
- }
- if (showWarning)
- {
- if (!EditorUtility.DisplayDialog("注意", "重新生成Prefab Label?", "确定", "取消"))
- {
- return;
- }
- }
- if (!regist)
- {
- regist = EditorUtility.DisplayDialog("提示", "是否自动注册", "确定", "取消");
- }
- List<string> labels = new List<string>();
- List<Transform> transforms = GetAllTransformFromPrefab(labelSet.Prefabs);
- foreach (var transform in transforms)
- {
- labels.Add($"{labelSet.LabePrefix} {transform.name} = \"{transform.name}\";");
- }
- InsertLineToScript(StartMark, EndMark, labelSet.LabelScript, labels);
- if (regist)
- {
- CreateComponentsFromPrefab(labelSet, false);
- }
- }
- public static void CreateLabelFromLanguageXml(LabelSet labelSet, bool showWarning = true) //todo 更新
- {
- if (labelSet.LabelScript == null)
- {
- Debug.LogError("LabelScript is null");
- return;
- }
- if (showWarning)
- {
- if (!EditorUtility.DisplayDialog("注意", "重新生成LanguageXml Label?", "确定", "取消"))
- {
- return;
- }
- }
- List<string> labels = new List<string>();
- foreach (var language in labelSet.Languages)
- {
- XmlDocument document = new XmlDocument();
- document.LoadXml(language.text);
- XmlNodeList childNodes = document.SelectSingleNode("lan").ChildNodes;
- for (int i = 0; i < childNodes.Count; i++)
- {
- labels.AddRange(GetAllLabelFromXmlNode(childNodes[i], labelSet));
- }
- }
- InsertLineToScript(StartMark, EndMark, labelSet.LabelScript, labels);
- }
- private static List<string> GetAllLabelFromXmlNode(XmlNode node, LabelSet labelSet) //todo 增加
- {
- List<string> labels = new List<string>();
- for (int i = 0; i < node.ChildNodes.Count; i++)
- {
- XmlNode childNode = node.ChildNodes[i];
- string label;
- if (i == 0)
- {
- label = $"\t{labelSet.LabePrefix} {node.Name} = \"{node.Name}\";";
- labels.Add(label);
- }
- label = $"\t{labelSet.LabePrefix} {node.Name}{LanguageLabel.LanguagePageSeperator}{childNode.Name} = \"{node.Name}{LanguageLabel.LanguagePageSeperator}{childNode.Name}\";";
- labels.Add(label);
- }
- return labels;
- }
- public static Type GetType(ComponentType componentType)
- {
- Assembly assembly = Assembly.Load("UnityEngine.UI");
- Type type = assembly.GetType($"UnityEngine.UI.{componentType}");
- if (type == null)
- {
- assembly = Assembly.Load("UnityEngine");
- type = assembly.GetType($"UnityEngine.{componentType}");
- }
- if (type == null)
- {
- assembly = Assembly.Load("Assembly-CSharp");
- type = assembly.GetType($"{componentType}");
- }
- return type;
- }
- public static void CreateComponentsFromPrefab(LabelSet labelSet, bool showWarning = true) //todo 更新
- {
- if (labelSet.ComponentScript == null)
- {
- Debug.LogError("ComponentScript is null");
- return;
- }
- if (showWarning)
- {
- if (!EditorUtility.DisplayDialog("注意", "重新生成PrefabComponent?", "确定", "取消"))
- {
- return;
- }
- }
- List<string> defineStrings = new List<string>();
- List<string> registStrings = new List<string>();
- List<string> eventNames = new List<string>();
- List<string> registEventStrings = new List<string>();
- registStrings.AddRange(labelSet.RegistExtraLines);
- foreach (var registTarget in labelSet.RegistTargets)
- {
- if (registTarget.Ignore) continue;
- defineStrings.Add($"{labelSet.ComponentPrefix} {registTarget.Type} {registTarget.Transform.name};");
- string registString = labelSet.RegistString.Replace("#NAME", registTarget.Transform.name).Replace("#TYPE", registTarget.Type.ToString()).Replace("#NEWNAME", registTarget.Name);
- if (labelSet.LabelScript != null)
- {
- registString = registString.Replace("#LABEL", labelSet.LabelScript.name);
- }
- registStrings.Add(registString);
- foreach (var eventString in InstanceManager.SearchInstance<LabelUtility>().EventStrings)
- {
- if (eventString.ComponentType == registTarget.Type)
- {
- if (!registTarget.CustomEvent)
- {
- continue;
- }
- for (int i = 0; i < eventString.MethodNames.Count; i++)
- {
- eventNames.Add($"{eventString.MethodNames[i].Replace("#NEWNAME", registTarget.Name).Replace("#NAME", registTarget.Transform.name)}");
- }
- for (int i = 0; i < eventString.RegistStrings.Count; i++)
- {
- registEventStrings.Add($"{eventString.RegistStrings[i].Replace("#NEWNAME", registTarget.Name).Replace("#NAME", registTarget.Transform.name)};");
- }
- }
- }
- }
- //foreach (var eventString in eventStrings)
- //{
- // Debug.Log(eventString);
- //}
- int? startIndex = null;
- int? endIndex = null;
- List<string> oldEventMethods = GetScriptContentBetweenMarks(EventStartMark, EventEndMark, labelSet.ComponentScript, ref startIndex, ref endIndex);
- List<string> newEventMethods = new List<string>();
- int? tabAmount = GetMarkSpaceAmount(labelSet.ComponentScript, EventStartMark);
- for (int i = 0; i < eventNames.Count; i++)
- {
- List<string> methodStrings = TryGetMethodStrings(eventNames[i], oldEventMethods);
- if (methodStrings.Valid())
- {
- for (int j = 0; j < methodStrings.Count; j++)
- {
- if (tabAmount == null)
- {
- newEventMethods.Add(methodStrings[j]);
- }
- else
- {
- //Debug.Log((int)methodStrings[j][0]);
- //Debug.Log((int)methodStrings[j][1]);
- //Debug.LogWarning(methodStrings[j]);
- //Debug.Log(methodStrings[j].Length);
- string str = methodStrings[j].Length > 0 ? methodStrings[j].Substring(tabAmount.Value) : methodStrings[j];
- newEventMethods.Add(str);
- }
- }
- if (i < eventNames.Count - 1)
- {
- newEventMethods.Add("");
- }
- }
- else
- {
- newEventMethods.Add($"{labelSet.ComponentPrefix} {eventNames[i]}");
- newEventMethods.Add("{\r\n");
- newEventMethods.Add(i < eventNames.Count - 1 ? "}\r\n" : "}");
- }
- }
- InsertLineToScript(StartMark, EndMark, labelSet.ComponentScript, defineStrings);
- InsertLineToScript(RegistStartMark, RegistEndMark, labelSet.ComponentScript, registStrings);
- InsertLineToScript(RegistEventStartMark, RegistEventEndMark, labelSet.ComponentScript, registEventStrings);
- InsertLineToScript(EventStartMark, EventEndMark, labelSet.ComponentScript, newEventMethods);
- //foreach (var registEventString in registEventStrings)
- //{
- // Debug.Log(registEventString);
- //}
- //List <string> typeNames = new List<string>();
- //foreach (var purview in labelSet.RegistTypes)
- //{
- // typeNames.Add(purview.ToString());
- //}
- //List <Transform> transforms = GetAllTransformFromPrefab(labelSet.Prefabs);
- //Dictionary<string, List<string>> namesDictionary = new Dictionary<string, List<string>>();
- //foreach (var name in typeNames)
- //{
- // namesDictionary.Add(name, new List<string>());
- //}
- //foreach (var kv in namesDictionary)
- //{
- // Assembly assembly = Assembly.Load("UnityEngine.UI");
- // Type type = assembly.GetType($"UnityEngine.UI.{kv.Key}");
- // if (type == null)
- // {
- // assembly = Assembly.Load("UnityEngine");
- // type = assembly.GetType($"UnityEngine.{kv.Key}");
- // }
- // if (type == null)
- // {
- // assembly = Assembly.Load("Assembly-CSharp");
- // type = assembly.GetType($"{kv.Key}");
- // }
- // foreach (var transform in transforms)
- // {
- // if (transform.GetComponent(type) == null) continue;
- // namesDictionary[kv.Key].Add(transform.name);
- // }
- //}
- //List<string> names = new List<string>();
- //List<string> components = new List<string>();
- //List<string> registStrings = new List<string>();
- //registStrings.AddRange(labelSet.RegistExtraLines);
- //foreach (var kv in namesDictionary)
- //{
- // foreach (var name in kv.Value)
- // {
- // names.Add(name);
- // string newName = string.IsNullOrEmpty(labelSet.NameExcludeString) ? name : name.Replace(labelSet.NameExcludeString, "");
- // components.Add($"{labelSet.ComponentPrefix} {kv.Key} {newName};");
- // string registString = labelSet.RegistString.Replace("#NAME", name).Replace("#TYPE", kv.Key).Replace("#NEWNAME", newName);
- // if (labelSet.LabelScript != null)
- // {
- // registString = registString.Replace("#LABEL", labelSet.LabelScript.name);
- // }
- // registStrings.Add(registString);
- // }
- //}
- //InsertLineToScript(StartMark, EndMark, labelSet.ComponentScript, components);
- //InsertLineToScript(RegistStartMark, RegistEndMark, labelSet.ComponentScript, registStrings);
- }
- private static List<string> TryGetMethodStrings(string methodName, List<string> strings)
- {
- List<string> results = new List<string>();
- for (int i = 0; i < strings.Count; i++)
- {
- if (!strings[i].Contains(methodName)) continue;
- for (int j = i; j < strings.Count; j++)
- {
- results.Add(strings[j]);
- if (strings[j].Trim() == "}")
- {
- return results;
- }
- }
- }
- return results;
- }
- private static void InsertLineToScript(int startIndex, TextAsset textAsset, List<string> insertLines)
- {
- List<string> strings = GetScriptContents(textAsset);
- int prefixIndex = strings[startIndex].IndexOf("//");
- string prefix = strings[startIndex].Substring(0, prefixIndex);
- for (int i = 0; i < insertLines.Count; i++)
- {
- strings.Insert(startIndex, prefix + insertLines[i]);
- startIndex++;
- }
- StringBuilder stringBuilder = new StringBuilder();
- for (int i = 0; i < strings.Count; i++)
- {
- stringBuilder.AppendLine(strings[i]);
- }
- string content = stringBuilder.ToString();
- content = content.Substring(0, content.Length - 2);
- File.WriteAllText(AssetDatabase.GetAssetPath(textAsset), content);
- AssetDatabase.Refresh();
- }
- private static void InsertLineToScript(string startMark, string endMark, TextAsset textAsset, List<string> insertLines)
- {
- int? startMarkLineIndex = null;
- int? endMarkLineIndex = null;
- List<string> strings = GetScriptContentAfterClearMarks(startMark, endMark, textAsset, ref startMarkLineIndex, ref endMarkLineIndex);
- int prefixIndex = strings[startMarkLineIndex.Value].IndexOf("//");
- string prefix = strings[startMarkLineIndex.Value].Substring(0, prefixIndex);
- for (int i = 0; i < insertLines.Count; i++)
- {
- strings.Insert(startMarkLineIndex.Value + 1, prefix + insertLines[i]);
- startMarkLineIndex++;
- }
- StringBuilder stringBuilder = new StringBuilder();
- for (int i = 0; i < strings.Count; i++)
- {
- stringBuilder.AppendLine(strings[i]);
- }
- string content = stringBuilder.ToString();
- content = content.Substring(0, content.Length - 2);
- File.WriteAllText(AssetDatabase.GetAssetPath(textAsset), content);
- AssetDatabase.Refresh();
- }
- private static int? GetMarkIndex(TextAsset textAsset, string mark)
- {
- List<string> strings = textAsset.text.Split(new[] { "\r\n" }, StringSplitOptions.None).ToList();
- for (int i = 0; i < strings.Count; i++)
- {
- if (strings[i].Contains(mark))
- {
- return i;
- }
- }
- return null;
- }
- private static int? GetMarkSpaceAmount(TextAsset textAsset, string mark)
- {
- List<string> strings = textAsset.text.Split(new[] { "\r\n" }, StringSplitOptions.None).ToList();
- for (int i = 0; i < strings.Count; i++)
- {
- if (strings[i].Contains(mark))
- {
- if (Regex.Match(strings[i], "^\\s+").Success)
- {
- //Debug.Log(Regex.Match(strings[i], "^\\s+").Length);
- return Regex.Match(strings[i], "^\\s+").Length;
- }
- else
- {
- return null;
- }
- }
- }
- return null;
- }
- private static List<string> GetScriptContentBetweenMarks(string startMark, string endMark, TextAsset textAsset, ref int? startMarkLineIndex, ref int? endMarkLineIndex)
- {
- //Debug.Log(textAsset.text);
- List<string> strings = textAsset.text.Split(new[] { "\r\n" }, StringSplitOptions.None).ToList();
- for (int i = 0; i < strings.Count; i++)
- {
- if (strings[i].Contains(startMark))
- {
- //Debug.Log(strings[i][0]);
- //Debug.LogWarning(strings[i][1]);
- //Debug.Log(strings[i][2]);
- //Debug.LogWarning(strings[i][3]);
- //Debug.Log(strings[i][4]);
- //Debug.LogWarning(strings[i][5]);
- startMarkLineIndex = i;
- }
- else if (strings[i].Contains(endMark))
- {
- endMarkLineIndex = i;
- }
- }
- List<string> results = new List<string>();
- for (int i = startMarkLineIndex.Value + 1; i < endMarkLineIndex.Value; i++)
- {
- //if (strings[i].Length > 0)
- //{
- // Debug.Log(strings[i][0]);
- //}
- //if (strings[i].Length > 1)
- //{
- // Debug.LogWarning(strings[i][1]);
- //}
- results.Add(strings[i]);
- }
- return results;
- }
- private static List<string> GetScriptContents(TextAsset textAsset)
- {
- List<string> strings = textAsset.text.Split(new[] { "\r\n" }, StringSplitOptions.None).ToList();
- return strings;
- }
- private static List<string> GetScriptContentAfterClearMarks(string startMark, string endMark, TextAsset textAsset, ref int? startMarkLineIndex, ref int? endMarkLineIndex)
- {
- List<string> strings = textAsset.text.Split(new[] {"\r\n"}, StringSplitOptions.None).ToList();
- //List<string> currentDefinedNames = new List<string>();
- for (int i = 0; i < strings.Count; i++)
- {
- if (strings[i].Contains(startMark))
- {
- startMarkLineIndex = i;
- }
- else if (strings[i].Contains(endMark))
- {
- endMarkLineIndex = i;
- }
- //if (startMarkLineIndex != null)
- //{
- // if (endMarkLineIndex != null)
- // {
- // if (i > startMarkLineIndex.Value && i < endMarkLineIndex.Value)
- // {
- // currentDefinedNames.Add(GetDefinedName(strings[i]));
- // }
- // }
- // else
- // {
- // if (i > startMarkLineIndex.Value)
- // {
- // currentDefinedNames.Add(GetDefinedName(strings[i]));
- // }
- // }
- //}
- }
- int definedCount = endMarkLineIndex.Value - startMarkLineIndex.Value - 1;
- for (int i = 0; i < definedCount; i++)
- {
- strings.RemoveAt(startMarkLineIndex.Value + 1);
- }
- return strings;
- }
- private static List<Transform> GetAllTransformFromPrefab(List<GameObject> prefabs)
- {
- List<Transform> transforms = new List<Transform>();
- for (int i = 0; i < prefabs.Count; i++)
- {
- transforms.AddRange(prefabs[i].GetComponentsInChildren<Transform>(true));
- }
- return transforms;
- }
- }
- #endif
- }
|