コード例 #1
0
        public static string parseClear(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length >= 0 && args.Length < 3)
            {
                string output = "clear ";
                if (args.Length == 0)
                {
                    output += "@s";
                }
                else if (context.isEntity(args[0]))
                {
                    output += context.GetEntitySelector(args[0]);
                }
                else
                {
                    output += "@s " + args[0];
                }

                for (int i = 1; i < Math.Min(2, args.Length); i++)
                {
                    output += " " + Compiler.smartEmpty(args[i]);
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #2
0
        public static string parseEffect(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length < 7)
            {
                string output;
                if (args[0] != "clear")
                {
                    if (context.isEntity(args[1]))
                    {
                        output = "effect give " + context.GetEntitySelector(args[1]) + " " + Compiler.smartEmpty(args[2]) + " " + Compiler.smartEmpty(args[3]) + " " + Compiler.smartEmpty(args[4]) + " " + Compiler.smartEmpty(args[5]);
                    }
                    else
                    {
                        output = "effect give @s " + Compiler.smartEmpty(args[1]) + " " + Compiler.smartEmpty(args[2]) + " " + Compiler.smartEmpty(args[3]) + " " + Compiler.smartEmpty(args[4]);
                    }
                }
                else
                {
                    if (context.isEntity(args[1]))
                    {
                        output = "effect clear " + context.GetEntitySelector(args[1]) + " " + Compiler.smartEmpty(args[2]);
                    }
                    else
                    {
                        output = "effect clear @s " + Compiler.smartEmpty(args[1]);
                    }
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #3
0
        public static string parseStopsound(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length > 0)
            {
                string output = "stopsound ";
                if (context.isEntity(args[0]))
                {
                    output += context.GetEntitySelector(args[0]);
                }
                else
                {
                    output += "@s " + args[0];
                }

                for (int i = 1; i < args.Length; i++)
                {
                    output += " " + Compiler.smartEmpty(args[i]);
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #4
0
        public static string parseTP(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 1 || (args.Length == 2 && context.isEntity(args[0])))
            {
                string output = "tp";

                if (args.Length == 1)
                {
                    output += "@s " + args[0];
                }
                else
                {
                    for (int i = 0; i < args.Length; i++)
                    {
                        output += " " + args[i];
                    }
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #5
0
        public static string parseFill(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 1)
            {
                string output = "fill";
                Regex  r      = new Regex(@"#[\w\.]+");
                for (int i = 0; i < args.Length; i++)
                {
                    Match m = r.Match(args[i]);
                    if (m.Success)
                    {
                        output += " " + Compiler.regReplace(args[i], m, "#" + Compiler.Core.FormatTagsPath(context.GetBlockTags(m.Value.Replace("#", ""))));
                    }
                    else
                    {
                        output += " " + args[i];
                    }
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #6
0
        public static string parseTellraw(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            string output = "tellraw " + context.GetEntitySelector(args[0]) + " ";

            string[] json = Compiler.Core.FormatJson(args, context, 1);
            output = json[1] + output + json[0] + "\n" + json[2];

            return(output + '\n');
        }
コード例 #7
0
        public string jsonSubArg(string[] subargs, Compiler.Context context)
        {
            string output = "";

            for (int j = 1; j < subargs.Length; j++)
            {
                //throw new Exception("Not supported!");
            }
            return(output);
        }
コード例 #8
0
        public static string parseGamemode(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 2 && context.isEntity(args[0]))
            {
                int    tmpI;
                string output;
                if (int.TryParse(args[1], out tmpI))
                {
                    output = "gamemode " + difficulties[tmpI] + " " + context.GetEntitySelector(args[0]);
                }
                else
                {
                    output = "gamemode " + Compiler.smartEmpty(args[1]) + " " + context.GetEntitySelector(args[0]);
                }

                return(output + '\n');
            }
            else if (args.Length == 2 && context.isEntity(args[1]))
            {
                int    tmpI;
                string output;
                if (int.TryParse(args[0], out tmpI))
                {
                    output = "gamemode " + difficulties[tmpI] + " " + context.GetEntitySelector(args[1]);
                }
                else
                {
                    output = "gamemode " + Compiler.smartEmpty(args[0]) + " " + context.GetEntitySelector(args[1]);
                }

                return(output + '\n');
            }
            else if (args.Length == 1)
            {
                int    tmpI;
                string output;
                if (int.TryParse(args[0], out tmpI))
                {
                    output = "gamemode " + difficulties[tmpI] + " @s";
                }
                else
                {
                    output = "gamemode " + Compiler.smartEmpty(args[0]) + " @s";
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #9
0
 public static string parseStructure(string[] args, Compiler.Context context, string text, int rec = 0)
 {
     if (args.Length == 1)
     {
         string output = "setblock ~ ~ ~ minecraft:structure_block[mode = load]{ignoreEntities: 0b,rotation: \"NONE\",mode: \"LOAD\",integrity: 1.0f,name: \"" + Compiler.Project.ToLower() + ":" + args[0].Replace("\"", "") + "\",showboundingbox: 1b}";
         output += "\nsetblock ~ ~1 ~ redstone_block";
         return(output + '\n');
     }
     else
     {
         return(Compiler.functionEval(text, null, "=", rec + 1));
     }
 }
コード例 #10
0
        public static string parseGamerule(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 2)
            {
                string output = "gamerule " + Compiler.smartEmpty(args[0]) + " " + Compiler.smartEmpty(args[1]);

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #11
0
        public static string parseTitle(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            string titleType = Compiler.smartEmpty(args[1]);

            if (titleType != "actionbar" && titleType != "title" && titleType != "subtitle")
            {
                throw new Exception("Invalid Title type: " + titleType);
            }

            string output = "title " + context.GetEntitySelector(args[0]) + " " + titleType + " ";

            string[] json = Compiler.Core.FormatJson(args, context, 2);
            output = json[1] + output + json[0] + "\n" + json[2];
            return(output + '\n');
        }
コード例 #12
0
        public static string parseWeather(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 1)
            {
                string output = "weather";

                for (int i = 0; i < args.Length; i++)
                {
                    output += " " + Compiler.smartEmpty(args[i]);
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #13
0
        public static string parseSay(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 1)
            {
                string output = "say ";

                for (int i = 0; i < args.Length; i++)
                {
                    output += args[i] + " ";
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #14
0
        public static string parseDifficulty(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            if (args.Length == 1)
            {
                int    tmpI;
                string output;
                if (int.TryParse(args[0], out tmpI))
                {
                    output = "difficulty " + difficulties[tmpI];
                }
                else
                {
                    output = "difficulty " + Compiler.smartEmpty(args[0]);
                }

                return(output + '\n');
            }
            else
            {
                return(Compiler.functionEval(text, null, "=", rec + 1));
            }
        }
コード例 #15
0
 public abstract string[] FormatJson(string[] args, Compiler.Context context, int start = 0);
コード例 #16
0
        public static string parseMagicTitle(string[] args, Compiler.Context context, string text, int rec = 0)
        {
            int maxTime;
            int argIndex = 1;

            if (!int.TryParse(Compiler.smartEmpty(args[1]), out maxTime))
            {
                maxTime  = -1;
                argIndex = 0;
            }

            string titleType = Compiler.smartEmpty(args[argIndex + 2]);

            if (titleType != "actionbar" && titleType != "title" && titleType != "subtitle")
            {
                throw new Exception("Invalid Title type: " + titleType);
            }

            string titleLine = "title " + context.GetEntitySelector(args[argIndex + 1]) + " " + titleType + " ";
            string output    = "";
            int    time      = 0;

            for (int i = argIndex + 3; i < args.Length; i++)
            {
                string   arg     = Compiler.smartEmpty(args[i]).StartsWith("(") ? Compiler.smartEmpty(args[i].Substring(args[i].IndexOf('(') + 1, args[i].LastIndexOf(')') - args[i].IndexOf('(') - 1)) : args[i];
                string[] subargs = Compiler.smartSplit(arg, ',');

                if (subargs[0].StartsWith("\""))
                {
                    for (int j = 1; j < subargs[0].Length - 1; j++)
                    {
                        if (subargs[0][j] == '\\')
                        {
                            if (subargs[0][j + 1] == 'u')
                            {
                                while (Char.IsHighSurrogate((char)Convert.ToInt32(subargs[0].Substring(j, 6).ToUpper().Replace("\\U", "0x"), 16)))
                                {
                                    j += 6;
                                }
                                j += 5;
                            }
                            else
                            {
                                j++;
                            }
                        }

                        string[] json = new string[i - 2 - argIndex];
                        for (int k = argIndex + 3; k < i; k++)
                        {
                            json[k - 3 - argIndex] = args[k];
                        }
                        json[i - 3 - argIndex] = "(\"" + subargs[0].Substring(1, j) + "\"";
                        for (int k = 1; k < subargs.Length; k++)
                        {
                            json[i - 3 - argIndex] += "," + subargs[k];
                        }
                        json[i - 3 - argIndex] += ")";
                        string[] jsonParsed = Compiler.Core.FormatJson(json, context, 0);
                        output += "execute if score " + Compiler.GetVariableByName(args[0]).scoreboard() + " matches " + time.ToString() + " run " + titleLine + jsonParsed[0] + "\n";
                        time++;
                    }
                }
                else
                {
                    string[] json = new string[i - 2];
                    for (int k = argIndex + 3; k <= i; k++)
                    {
                        json[k - 3 - argIndex] = args[k];
                    }

                    string[] jsonParsed = Compiler.Core.FormatJson(json, context, 0);
                    output += "execute if score " + Compiler.GetVariableByName(args[0]).scoreboard() + " matches " + time.ToString() + " run " + titleLine + jsonParsed[0] + "\n";
                    time++;
                }
            }
            string[] jsonParsedGlobal = Compiler.Core.FormatJson(args, context, 3 + argIndex);
            output += "execute if score " + Compiler.GetVariableByName(args[0]).scoreboard() + " matches " + time.ToString() + ".. run " + titleLine + jsonParsedGlobal[0] + "\n";
            if (maxTime > -1)
            {
                output += "execute if score " + Compiler.GetVariableByName(args[0]).scoreboard() + " matches " + (time + maxTime).ToString() + ".. run scoreboard players set " + Compiler.GetVariableByName(args[0]).scoreboard() + " -100000\n";
            }
            return(jsonParsedGlobal[1] + output + jsonParsedGlobal[2] + '\n');
        }
コード例 #17
0
        public string[] FormatJsonInternal(string[] args, Compiler.Context context, int start = 0)
        {
            string           output        = "[";
            string           output2       = "";
            string           output3       = "";
            int              strTag        = 0;
            HashSet <string> unpackedFloat = new HashSet <string>();

            for (int i = start; i < args.Length; i++)
            {
                string   arg          = Compiler.smartEmpty(args[i]).StartsWith("(") ? Compiler.smartEmpty(args[i].Substring(args[i].IndexOf('(') + 1, args[i].LastIndexOf(')') - args[i].IndexOf('(') - 1)) : args[i];
                string[] subargs      = Compiler.smartSplit(arg, ',');
                bool     ignoreFormat = false;
                if (subargs[0].Contains("\""))
                {
                    string ext = Compiler.smartExtract(subargs[0]);
                    if (ext.StartsWith("\"") && ext.EndsWith("\""))
                    {
                        output += ",{\"text\":" + subargs[0];
                    }
                    else if (ext.StartsWith("f\"") && ext.EndsWith("\""))
                    {
                        string[] part = Compiler.extractString(ext.Substring(1, ext.Length - 1)).Replace("{", "}").Split('}');

                        var a2     = Enumerable.Range(0, part.Length);
                        var recArg = (subargs.Length > 1) ? subargs.Skip(1).Aggregate((x, y) => x + "," + y) : "";
                        var part2  = part.Zip(a2, (first, second) => second % 2 == 0 ? "\"" + first + "\"" : first)
                                     .Where(x => x != "\"\"")
                                     .Select(x => "(" + x + "," + recArg + ")")
                                     .Aggregate((x, y) => x + "," + y);


                        string[] outs = FormatJsonInternal(Compiler.smartSplit(part2, ','), context);
                        output  += "," + outs[0].Substring(1, outs[0].Length - 2);
                        output2 += outs[1];
                        output3 += outs[2];


                        ignoreFormat = true;
                    }
                    else
                    {
                        throw new Exception("JSON Syntaxe Error");
                    }
                }
                else if (subargs[0].Contains("@"))
                {
                    output += ",{\"selector\":\"" + subargs[0] + "\"";
                }
                else if (float.TryParse(subargs[0], out float _))
                {
                    output += ",{\"text\":\"" + subargs[0] + "\"";
                }
                else if (Compiler.isStringVar(subargs[0]))
                {
                    string tmp = Compiler.getString(subargs[0]);
                    tmp    += "tag @e[tag=__str__,tag=!__str__tag__] add __str_" + strTag.ToString() + "\n";
                    tmp    += "tag @e[tag=__str__,tag=!__str__tag__] add __str__tag__" + "\n";
                    output += ",{\"selector\":\"" + "@e[tag=__str_" + strTag.ToString() + "]" + "\"";
                    strTag++;
                    output2 += tmp;
                }
                else if (context.GetVarType(subargs[0]) == Compiler.Type.ENTITY)
                {
                    output += ",{\"selector\":\"" + context.GetEntitySelector(subargs[0]) + "\"";
                }
                else if (context.GetVarType(subargs[0]) == Compiler.Type.ARRAY)
                {
                    int nb = Compiler.GetVariable(context.GetVariable(subargs[0])).arraySize;
                    ignoreFormat = true;
                    for (int j = 0; j < Compiler.GetVariable(context.GetVariable(subargs[0])).arraySize; j++)
                    {
                        var va = Compiler.GetVariable(context.GetVariable(subargs[0] + "." + j.ToString()));
                        if (va.type == Compiler.Type.STRING)
                        {
                            string tmp = Compiler.getString(subargs[0]);
                            tmp    += "tag @e[tag=__str__,tag=!__str__tag__] add __str_" + strTag.ToString() + "\n";
                            tmp    += "tag @e[tag=__str__,tag=!__str__tag__] add __str__tag__" + "\n";
                            output += ",{\"selector\":\"" + "@e[tag=__str_" + strTag.ToString() + "]" + "\"";
                            output += jsonSubArg(subargs, context);
                            output += "}";
                            strTag++;
                            output2 += tmp;
                        }
                        else
                        {
                            if (j == 0)
                            {
                                output += ",{\"text\":" + "\"[\"";
                                output += jsonSubArg(subargs, context);
                                output += "}";
                            }
                            string[] v = Compiler.GetVariableByName(subargs[0] + "." + j.ToString()).scoreboard().Split(' ');
                            output += ",{ \"score\":{ \"name\":\"" + v[0] + "\",\"objective\":\"" + v[1] + "\"}";
                            output += jsonSubArg(subargs, context);
                            output += "}";
                            output += ",{\"text\":" + "\", \"";
                            output += jsonSubArg(subargs, context);
                            output += "}";
                            if (j == nb - 1)
                            {
                                output += ",{\"text\":" + "\"]\"";
                                output += jsonSubArg(subargs, context);
                            }
                        }
                    }
                }
                else if (context.GetVarType(subargs[0]) == Compiler.Type.STRUCT)
                {
                    Compiler.Structure s = Compiler.structs[Compiler.GetVariableByName(subargs[0]).enums];
                    output += ",{\"text\":\"" + s.name + "(" + "\"";
                    output += jsonSubArg(subargs, context);
                    output += "}";
                    foreach (var v in s.fields)
                    {
                        output += ",{\"text\":\"" + v.name + " = " + "\"";
                        output += jsonSubArg(subargs, context);
                        output += "}";

                        string tmp = FormatJsonInternal(new string[] { subargs[0] + "." + v.name }, context, 0)[0];
                        output += "," + tmp.Substring(1, tmp.Length - 2);

                        output += ",{\"text\":\"" + ", " + "\"";
                        output += jsonSubArg(subargs, context);
                        output += "}";
                    }
                    output += ",{\"text\":\"" + ")" + "\"";
                }
                else if (context.GetVarType(subargs[0]) == Compiler.Type.FLOAT)
                {
                    var v = Compiler.GetVariableByName(subargs[0]);
                    if (!unpackedFloat.Contains(v.gameName))
                    {
                        output2 += Compiler.parseLine($"int {v.gameName}.u #= {v.gameName}") + "\n";
                        output2 += Compiler.parseLine($"{v.gameName}.u /={Compiler.compilerSetting.FloatPrecision}") + "\n";
                        output2 += Compiler.parseLine($"int {v.gameName}.l #= {v.gameName}") + "\n";
                        output2 += Compiler.parseLine($"{v.gameName}.l %={Compiler.compilerSetting.FloatPrecision}") + "\n";

                        unpackedFloat.Add(v.gameName);
                    }
                    var vu = Compiler.GetVariableByName($"{v.gameName}.u").scoreboard().Split(' ');
                    var vl = Compiler.GetVariableByName($"{v.gameName}.l").scoreboard().Split(' ');
                    output += ",{ \"score\":{ \"name\":\"" + vu[0] + "\",\"objective\":\"" + vu[1] + "\"}";
                    output += jsonSubArg(subargs, context) + "}";
                    output += ",{\"text\":\".\"";
                    output += jsonSubArg(subargs, context) + "}";
                    output += ",{ \"score\":{ \"name\":\"" + vl[0] + "\",\"objective\":\"" + vl[1] + "\"}";
                }
                else
                {
                    string[] v = Compiler.GetVariableByName(subargs[0]).scoreboard().Split(' ');
                    output += ",{ \"score\":{ \"name\":\"" + v[0] + "\",\"objective\":\"" + v[1] + "\"}";
                }
                if (!ignoreFormat)
                {
                    output += jsonSubArg(subargs, context);
                }
                if (!ignoreFormat)
                {
                    output += "}";
                }
            }

            output += "]";

            if (strTag > 0)
            {
                output3 += "\nkill @e[tag=__str__]";
            }
            output = "[" + output.Substring(2, output.Length - 2);
            return(new string[] { output, output2, output3 });
        }
コード例 #18
0
 public override string[] FormatJson(string[] args, Compiler.Context context, int start = 0)
 {
     string[] outs = FormatJsonInternal(args, context, start);
     return(new string[] { "{ \"rawtext\" :" + outs[0] + "}", outs[1], outs[2] });
 }
コード例 #19
0
        public static string parse(string text, Compiler.Context context, int rec = 0)
        {
            while (text.StartsWith(" "))
            {
                text = text.Substring(1, text.Length - 1);
            }
            string arg = text.Substring(text.IndexOf('(') + 1, text.LastIndexOf(')') - text.IndexOf('(') - 1);

            string[] args = Compiler.smartSplit(arg, ',');

            if (text.ToLower().StartsWith("structure"))
            {
                return(parseStructure(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("title"))
            {
                return(parseTitle(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("magictitle"))
            {
                return(parseMagicTitle(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("tellraw"))
            {
                return(parseTellraw(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("clear"))
            {
                return(parseClear(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("say"))
            {
                return(parseSay(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("effect"))
            {
                return(parseEffect(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("difficulty"))
            {
                return(parseDifficulty(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("gamemode"))
            {
                return(parseGamemode(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("gamerule"))
            {
                return(parseGamerule(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("fill"))
            {
                return(parseFill(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("stopsound"))
            {
                return(parseStopsound(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("weather"))
            {
                return(parseWeather(args, context, text, rec));
            }

            if (text.ToLower().StartsWith("tp"))
            {
                return(parseTP(args, context, text, rec));
            }

            throw new NotImplementedException(text.Split(' ')[0] + " is not implemented");
        }
コード例 #20
0
        public string jsonSubArg(string[] subargs, Compiler.Context context)
        {
            string output = "";

            for (int j = 1; j < subargs.Length; j++)
            {
                if (context.IsFunction(subargs[j]))
                {
                    output += ",\"clickEvent\":{ \"action\":\"run_command\",\"value\":\"function " +
                              Compiler.GetFunction(context.GetFunctionName(subargs[j]), new string[] { }).gameName + "\"}";
                }
                else if (subargs[j].StartsWith("\"http"))
                {
                    output += ",\"clickEvent\":{ \"action\":\"open_url\",\"value\":" + subargs[j] + "}";
                }
                else if (subargs[j].StartsWith("action="))
                {
                    output += ",\"clickEvent\":{ \"action\":\"run_command\",\"value\":\"/function " +
                              Compiler.GetFunction(context.GetFunctionName(subargs[j].Split('=')[1]), new string[] { }).gameName + "\"}";
                }
                else if (subargs[j].StartsWith("link"))
                {
                    output += ",\"clickEvent\":{ \"action\":\"open_url\",\"value\":" + Compiler.smartSplit(subargs[j], '=', 1)[1] + "}";
                }
                else if (subargs[j].StartsWith("font"))
                {
                    output += ",\"font\":" + Compiler.smartSplit(subargs[j], '=', 1)[1];
                }
                else if (subargs[j] == "bold")
                {
                    output += ",\"bold\":true";
                }

                else if (subargs[j] == "italic")
                {
                    output += ",\"italic\":true";
                }

                else if (subargs[j] == "strikethrough")
                {
                    output += ",\"strikethrough\":true";
                }

                else if (subargs[j] == "obfuscated")
                {
                    output += ",\"obfuscated\":true";
                }

                else if (subargs[j] == "underlined")
                {
                    output += ",\"underlined\":true";
                }

                else if (subargs[j].StartsWith("color"))
                {
                    string c = Compiler.smartSplit(subargs[j], '=', 1)[1];
                    c = c.Contains("\"") ? Compiler.extractString(c) : c;
                    if (!c.StartsWith("#") && !validColor.Contains(c))
                    {
                        throw new Exception($"Invalid Color: {c}");
                    }

                    output += $",\"color\":\"{ c }\"";
                }
                else
                {
                    string c = subargs[j];
                    c = c.Contains("\"") ? Compiler.extractString(c) : c;
                    if (!c.StartsWith("#") && !validColor.Contains(c))
                    {
                        throw new Exception($"Invalid Color: {c}");
                    }

                    output += $",\"color\":\"{ c }\"";
                }
            }
            return(output);
        }